Seat

Posted Tan_tan_tann

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Seat相关的知识,希望对你有一定的参考价值。

Seat

题解

我们可以先将男性位置的顺序去掉,单看成 1 , 2 , 3 , 4 , . . . , n 1,2,3,4,...,n 1,2,3,4,...,n的序列,先考虑女性的位置该怎么插,最后再加入男性的顺序。
很明显,对于 i i i i + 1 i+1 i+1位置之间的女性,她既不能为 i i i也不能为 i + 1 i+1 i+1。女性也看成一个序列 P P P,那么 P i ≠ i ∧ P i ≠ i + 1 P_{i}\\not =i\\wedge P_{i}\\not =i+1 Pi=iPi=i+1
这不是Three Permutations吗,要让找一个排列与其它两个排列都不同,转化成图就是一个在大小为 n n n的环。
所以我们只要 D P DP DP后加个容斥就可以得到 70 p t s 70pts 70pts了。
这个做法同样给了我们一个提示,我们可以用容斥的方法求出答案。

我们考虑有 x x x个位置不合法的情况可以怎么计算。
我们可以先枚举不合法的位置,除了这些不合法的位置,其它的男女都是随便放的,也就是 ( ( n − x ) ! ) 2 ((n-x)!)^2 ((nx)!)2
而这些不合法的位置肯定有相对的顺序,乘上 x ! x! x!
最后还要将这些不合法的位置放回排列中,我们相当于在 2 n − x 2n-x 2nx个元素中任选 x x x个,让这 x x x个延伸一位,表示一个不合法对占据的两位,有 ( 2 n − x x ) \\binom{2n-x}{x} (x2nx)
所以有 x x x个位置不合法的情况就有 ( ( n − x ) ! ) 2 x ! ( 2 n − x x ) ((n-x)!)^2x!\\binom{2n-x}{x} ((nx)!)2x!(x2nx)种,可以用容斥得到最后的答案,
A n s = ∑ i = 0 n ( − 1 ) i ( ( n − i ) ! ) 2 i ! ( 2 n − i i ) Ans=\\sum_{i=0}^{n}(-1)^i((n-i)!)^2i!\\binom{2n-i}{i} Ans=i=0n(1)i((ni)!)2i!(i2ni)

时间复杂度 O ( n ) O\\left(n\\right) O(n)

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL;
const LL INF=1000000000000000000LL;
const int mo=998244353;
const int inv2=499122177;
const int jzm=2333;
const int lim=100000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-7;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1LL)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1LL;}return t;}
int n,fac[MAXN],inv[MAXN],f[MAXN],ans;
void init(){
	fac[0]=fac[1]=inv[0]=inv[1]=f[1]=1;
	for(int i=2;i<=n+n;i++)
		fac[i]=1ll*i*fac[i-1]%mo,
		f[i]=1ll*(mo-mo/i)*f[mo%i]%mo,
		inv[i]=1ll*f[i]*inv[i-1]%mo;
}
int C(int x,int y){
	if(x<0||y<0||x<y)return 0;
	return 1ll*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
signed main(){
	read(n);init();
	for(int i=0;i<=n;i++){
		int tmp=1ll*fac[n-i]*fac[n-i]%mo*fac[i]%mo*add(C(n+n-i,i),C(n+n-i-1,i-1),mo)%mo*C(n,i)%mo;
		if(i&1)ans=add(ans,mo-tmp,mo);else ans=add(ans,tmp,mo);	
	} 
	printf("%d\\n",1ll*ans*f[n]%mo);
	return 0;
}

谢谢!!!

以上是关于Seat的主要内容,如果未能解决你的问题,请参考以下文章

简单Elixir游戏服设计-测试驱动?

855. Exam Room

Seat

leetcode1227. Airplane Seat Assignment Probability

volve_s90_seat

1386. Cinema Seat Allocation