2020杭电多校第五场1012-Set1

Posted ZLTJohn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020杭电多校第五场1012-Set1相关的知识,希望对你有一定的参考价值。

题目大意

分析

求概率可以转化成计数,那么对于第i个位置,就是求有多少种方案数不会选到i,除以总方案数即可,总方案数很简单,就是(n-1)!!。
假如我们把i剔除掉,断开的区间合并起来形成一个长度为n-1区间,那么这个区间有多少种合法方案数?显然是(n-2)!!。但真的有那么多方案不会选到i吗?
考虑不会选到i的方案数长什么样子:设每次选取的两个数为(x,y),那么我们要保证所有的x都小于i。而很显然(n-2)!!里包含了x大于i的方案。
观察到当i<n/2的时候,方案数肯定为0,而i>=n/2时,我们要保证方案的x均位于1~i-1。那么等价于保证i+1 ~n均对应某个y。现在我们只需要求,i+1 ~n的位置均对应y的方案数即可。设req=n-i,方案数为
C i − 1 r e q ∗ r e q !   ∗ ( i − 1 − r e q    − 1 ) ! ! C_i-1^req*req!\\ *(i-1-req \\ \\ -1)!! Ci1reqreq! (i1req  1)!!
前面两个因子表示,我要为后面的y,在1~i-1中要选req个对应的x,然后顺序可以乱安排。第三项表示前面剩下未确定的位置的总方案数:前面未确定的还剩i-1-req个,对应的合法方案数就是 (size-1)!!

代码

#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
#define fo(i,j,k) for(i=j;i<=k;i++)
#define fd(i,j,k) for(i=j;i>=k;i--)
#define cmax(a,b) (a=(a>b)?a:b)
#define cmin(a,b) (a=(a<b)?a:b)
typedef long long ll;
typedef double db;
const int N=5e6+5,M=1e6+5,mo=998244353;
ll irev[N],rev[N],rev2[N],f[N],ans,fac[N];
int T,n,i,j,req;
void irev_predo(int n,int p)

	int i;
	irev[1]=1;
	fo(i,2,n)
	
		irev[i]=-(ll)(p/i)*irev[p%i]%p;
		if (irev[i]<0) irev[i]+=p; 
	

void predo(int n)

	fac[0]=1;
	fo(i,1,n) fac[i]=fac[i-1]*i%mo;
	rev[1]=rev[0]=1;
	rev2[1]=rev2[0]=1;
	fo(i,2,n) rev[i]=rev[i-1]*irev[i]%mo,rev2[i]=rev2[i-2]*irev[i]%mo;
	f[0]=1;
	fo(i,0,n/2)
		f[i+1]=f[i]*(2*i+1)%mo*(i+1)%mo;
	fo(i,0,n/2) f[i]=f[i]*rev[i]%mo;

ll c(int n,int m)

	if (n>m||m<0||n<0) return 0;
	if (n==m) return 1;
    return 1ll*fac[m]*rev[n]%mo*rev[m-n]%mo;

void Print(ll x)

	if (!x) putchar('0');
	int w[20];
	w[0]=0;
	while (x) w[++w[0]]=x%10,x/=10;
	while (w[0]) putchar('0'+w[w[0]--]);
	
int main()

    freopen("12.in","r",stdin);
	freopen("12.out","w",stdout);
	n=5e6;
	irev_predo(n,mo);
	predo(n); 
	scanf("%d",&T);
	while(T--)
	
		scanf("%d",&n);
		fo(i,1,n)
		
			req=n-i;
			if (i-1<req) ans=0;
			else
			
				//c(req,i-1)*fac[req]%mo*f[]
				ans=c(req,i-1)*fac[req]%mo*f[(i-1-req)/2]%mo*rev2[n-1]%mo;
				
			Print(ans);
			if (i!=n) putchar(' ');
		
		putchar('\\n');
	
	

以上是关于2020杭电多校第五场1012-Set1的主要内容,如果未能解决你的问题,请参考以下文章

[2019杭电多校第五场][hdu6625]three arrays(01字典树)

[补]2019HDU杭电多校第五场H

[2019杭电多校第五场][hdu6624]fraction

[2019杭电多校第五场][hdu6628]permutation 1

[2019杭电多校第五场][hdu6629]string matching

[2019杭电多校第五场][hdu6630]permutation 2