zoukankan      html  css  js  c++  java
  • 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)

    【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)

    题面

    洛谷

    题解

    对于每一组询问,要求的东西本质上就是:

    [sum_{i=0}^{k}{mchoose i}{n-mchoose k-i}i^L ]

    如果没有后面那个部分,就是一个范德蒙恒等式,所以就要把这个(i^L)直接拆掉。
    然后直接拿第二类斯特林数来拆:

    [i^L=sum_{j=0}^Legin{Bmatrix}L\jend{Bmatrix}{ichoose j}j! ]

    于是就把答案拆成了:

    [egin{aligned} Ans&=sum_{i=0}^k{mchoose i}{n-mchoose k-i}i^L\ &=sum_{i=0}^{k}{mchoose i}{n-mchoose k-i}sum_{j=0}^Legin{Bmatrix}L\jend{Bmatrix}{ichoose j}j!\ &=sum_{j=0}^Legin{Bmatrix}L\jend{Bmatrix}j!sum_{i=0}^{k}{mchoose i}{n-mchoose k-i}{ichoose j} end{aligned}]

    然后发现(displaystyle {mchoose i}{ichoose j}={mchoose j}{m-jchoose i-j})
    然后就有:

    [egin{aligned} Ans&=sum_{j=0}^Legin{Bmatrix}L\jend{Bmatrix}j!{mchoose j}sum_{i=0}^{k}{n-mchoose k-i}{m-jchoose i-j}\ &=sum_{j=0}^Legin{Bmatrix}L\jend{Bmatrix}j!{mchoose j}{n-jchoose k-j}\ end{aligned}]

    这样子可以做到单次(O(L))
    于是预处理第二类斯特林数就行了。
    这题不知道为什么要卡常,不太理解卡常的意义合在......

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MOD 998244353
    #define MAX 524288
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
    int W[MAX],r[MAX];
    void NTT(int *P,int opt,int len)
    {
    	int l=0,N;for(N=1;N<len;N<<=1)++l;
    	for(int i=0;i<N;++i)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	for(int i=0;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);
    	for(int i=1;i<N;i<<=1)
    	{
    		int w=fpow(3,(MOD-1)/(i<<1));W[0]=1;
    		for(int k=1;k<i;++k)W[k]=1ll*W[k-1]*w%MOD;
    		for(int j=0,p=i<<1;j<N;j+=p)
    			for(int k=0;k<i;++k)
    			{
    				int X=P[j+k],Y=1ll*W[k]*P[i+j+k]%MOD;
    				P[j+k]=(X+Y)%MOD;P[i+j+k]=(X+MOD-Y)%MOD;
    			}
    	}
    	if(opt==-1)
    	{
    		reverse(&P[1],&P[N]);
    		for(int i=0,inv=fpow(N,MOD-2);i<N;++i)P[i]=1ll*P[i]*inv%MOD;
    	}
    }
    int n,m,T,L;
    int A[MAX],B[MAX],S[MAX];
    int jc[20000010],jv[20000010];
    int C(int n,int m){if(n<m||n<0||m<0)return 0;return 1ll*jc[n]*jv[m]%MOD*jv[n-m]%MOD;}
    int main()
    {
    	n=read();m=read();T=read();L=read();
    	jc[0]=jv[0]=jv[1]=1;int mx=max(L,n);
    	for(int i=1;i<=mx;++i)jc[i]=1ll*jc[i-1]*i%MOD;jv[mx]=fpow(jc[mx],MOD-2);
    	for(int i=mx-1;i;--i)jv[i]=1ll*jv[i+1]*(i+1)%MOD;
    	for(int i=0,d=1;i<=L;++i,d=MOD-d)A[i]=1ll*d*jv[i]%MOD;
    	for(int i=0;i<=L;++i)B[i]=1ll*fpow(i,L)*jv[i]%MOD;
    	int N;for(N=1;N<=L+L;N<<=1);
    	NTT(A,1,N);NTT(B,1,N);
    	for(int i=0;i<N;++i)S[i]=1ll*A[i]*B[i]%MOD;
    	NTT(S,-1,N);
    	while(T--)
    	{
    		int N=read(),M=read(),K=read(),ans=0,Lim=min(L,min(M,min(N,K)));;
    		for(int i=0;i<=Lim;++i)ans=(ans+1ll*S[i]*jv[M-i]%MOD*jc[N-i]%MOD*jv[K-i])%MOD;
    		ans=1ll*ans*jc[M]%MOD*jv[N]%MOD*jc[K]%MOD;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    iStylePDF c#集成开发示例
    纯js 实现 HTML 元素拖拽,
    前端自动滚动
    双向选择排序(暂定)
    uniapp 分享链接
    Could not find a declaration file for module 'vue-xxx'.
    精通JavaScript(重点内容笔记)更新中...
    如何让DIV模块随着页面固定和不固定
    序列不包含任何匹配元素
    PHPStorm配置Apache服务器(wampServer 版)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/11142152.html
Copyright © 2011-2022 走看看