zoukankan      html  css  js  c++  java
  • 题解 P4705 【玩游戏】

    这题是真的神仙啊...居然用的 stl 来卡常?

    话说 998244353 真的可以一眼 NTT ?

    noteskey

    所以说只要推柿子就好了但是有的地方的推导根本就想不到...

    我们令第 t 个答案为 (ANS_tover nm) ,除去 nm 其实就是算期望时要除去的方案数

    那么有:

    [egin{aligned}{}ANS_t=&sum_{i=1}^{n} sum_{j=1}^m (a_i+b_j)^t \=&sum_{i=1}^{n}sum_{j=1}^{m}sum_{k=0}^{t} egin{pmatrix} t\k end{pmatrix} a_i^{k}b_{j}^{t-k} \=&sum_{k=0}^{t} egin{pmatrix} t\k end{pmatrix} sum_{i=1}^{n}a_i^{k} sum_{j=1}^{m} b_{j}^{t-k} \=& sum_{k=0}^{t} egin{pmatrix} t\k end{pmatrix} Big( sum_{i=1}^{n}a_i^{k} Big) Big(sum_{j=1}^{m} b_{j}^{t-k} Big) \=&sum_{k=0}^{t} t! Big({ sum_{i=1}^{n}a_i^{k}over k! } Big) Big( {sum_{j=1}^{m} b_{j}^{t-k} over (t-k)!} Big) end{aligned} ]

    那么我们发现这个东西就是卷积的形式了,于是我们的任务就是快速算出后面两个表达式所对应的的多项式

    我们设:

    [egin{aligned} f(k)=sum_{i=1}^n a_i ^{k} \ g(k)=sum_{i=1}^{m}b_{i}^{k} end{aligned} ]

    那么我们只要求出 (f(1...t) ,g(1...t)) 即可

    但是求出来没有这么简单...

    我们考虑先求出:

    [f_j(x)=sum_{i=1}^{k}a_j^{i} ]

    然后我们令:

    [F(x)= sum_{i=1}^{n} f_{i}(x) ]

    那么 (F(x)) 的第 k 项就表示了

    [sum_{i=1}^{i} a_{i}^{k} x^k ]

    即:

    [[x^{k}]F(x)=sum_{i=1}^{i} a_{i}^{k} ]

    那么我们现在发现要求出 (f_{j=1...n}(x)) ,但是没有什么高效的办法能解决这个问题

    于是我们把 (f_{j}(x)) 中的上限 k 改掉,变成 (infty) ,这样我们就能用生成函数来解决了:

    [f_{j}(x)={1over 1- a_i x} ]

    然后就是把这些 (f_j(x)) 加起来了:

    [F(x)={1over 1-a_1x} +{1over 1-a_2x} + ...+{1over 1-a_nx} ]

    最后就是怎么合并这些 (f_j(x)) 的问题了,我们发现:

    [ln(1-a_ix)'={-a_iover 1-a_ix} ]

    发现这个东西和我们要求的东西蛮像的,那么这里又有:

    [egin{aligned}G(x)=&sum_{i=1}^{n} ln(1-a_ix)' \ F(x)=&-x·G(x)+n end{aligned} ]

    那么我们的任务就已经是求出 G(x) 了

    [G(x)=sum_{i=1}^{n} ln(1-a_ix)'= ln(prod_{i=1}^n (1-a_ix))' ]

    然后我们就要在优秀的时间内求出(prod_{i=1}^n (1-a_ix)) ,然后取个 Ln 再求个 Inv ,右移一位让最低项为 n , (F(x)) 就构造好了

    至于对 b 数组也是同样的求法,两个要求的多项式求出来后,我们还要让两个多项式除去对应的阶乘,然后再去卷积

    卷完积后也和最开始的式子一样,第 t 项乘上 t! ,然后别忘了我们还要除去 nm 才是最终的答案...

    最后就是顺序输出就好了

    code

    这没救了的压行【雾

    //by Judge
    #include<bits/stdc++.h>
    #define Rg register
    #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
    #define ll long long
    using namespace std;
    const int mod=998244353;
    const int iG=332748118;
    const int M=524288+3;
    typedef int arr[M];
    #ifndef Judge
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    #endif
    char buf[1<<21],*p1=buf,*p2=buf;
    inline int inc(int x,int y){return (x+y)%mod;}
    inline int mul(int x,int y){return 1ll*x*y%mod;}
    inline int dec(int x,int y){return (x-y+mod)%mod;}
    inline int read(){ int x=0,f=1; char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
    } char sr[1<<21],z[20];int CCF=-1,Z;
    inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
    inline void print(int x,char chr='
    '){
    	if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
    	while(z[++Z]=x%10+48,x/=10);
    	while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
    } int n,m,t,qq,rev,d,limit;
    arr a,b,f,g,fac,ifac,lg,r[20],D[21],G[2];
    inline int qpow(Rg int x,Rg int p=mod-2,Rg int s=1){
    	for(;p;p>>=1,x=mul(x,x)) if(p&1) s=mul(s,x); return s;
    }
    inline void prep(int n=262143){ for(limit=1;limit<=n;limit<<=1);
    	fac[0]=fac[1]=1; fp(i,2,limit) fac[i]=mul(fac[i-1],i);
    	fp(d,1,19){ lg[1<<d]=d; fp(i,0,(1<<d)-1)
    		r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
    	}
    	for(Rg int t=(mod-1)>>1,i=1,x,y;i<limit;i<<=1,t>>=1){
    		x=qpow(3,t),y=qpow(iG,t),G[0][i]=G[1][i]=1;
    		fp(k,1,i-1) G[1][i+k]=mul(G[1][i+k-1],x);
    		fp(k,1,i-1) G[0][i+k]=mul(G[0][i+k-1],y);
    	}
    }
    inline void init(int n){
    	for(limit=1;limit<n;limit<<=1); d=lg[limit];
    }
    inline void NTT(int* a,int tp){
    	fp(i,0,limit-1) if(i<r[d][i]) swap(a[i],a[r[d][i]]);
    	for(Rg int mid=1,I=2;mid<limit;mid<<=1,I<<=1)
    		for(Rg int j=0,x,y;j<limit;j+=I) fp(k,0,mid-1)
    			x=a[j+k],y=mul(a[j+k+mid],G[tp][mid+k]),
    			a[j+k]=inc(x,y),a[j+k+mid]=dec(x,y);
    	if(tp) return ; int inv=qpow(limit);
    	fp(i,0,limit-1) a[i]=mul(a[i],inv);
    }
    inline void Mul(int* a,int* b,int* c,int n){
    	static arr A,B; fp(i,0,n-1) A[i]=a[i],B[i]=b[i];
    	fill(A+n,A+limit,0),fill(B+n,B+limit,0),NTT(A,1),NTT(B,1);
    	fp(i,0,limit-1) A[i]=mul(A[i],B[i]); NTT(A,0),copy(A,A+limit,c);
    }
    void Inv(int* a,int* b,int n){
    	if(n==1) return b[0]=qpow(a[0]),void();
    	Inv(a,b,n>>1),init(n<<1); static arr c,d;
    	fp(i,0,n-1) c[i]=a[i],d[i]=b[i];
    	fp(i,n,limit-1) c[i]=d[i]=0; NTT(c,1),NTT(d,1);
    	fp(i,0,limit-1) c[i]=mul(c[i],mul(d[i],d[i])); NTT(c,0);
    	fp(i,0,n-1) b[i]=dec(inc(b[i],b[i]),c[i]);
    }
    inline void Derv(int* a,int* b,int n){
    	fp(i,1,n-1) b[i-1]=mul(a[i],i); b[n-1]=0;
    }
    inline void Ln(int* a,int* b,int n){ static arr c,d;
    	memset(c,0,(n+1)<<2),memset(d,0,(n+1)<<2);
    	Derv(a,c,n),Inv(a,d,n),init(n<<1);
    	Mul(c,d,b,n),fill(b+n,b+limit,0);
    }
    inline void solv(int* a,int d,int l,int r){
    	if(l==r) return D[d][0]=1,D[d][1]=mod-a[l],void(); static arr A,B;
    	int mid=(l+r)>>1; solv(a,d,l,mid),solv(a,d+1,mid+1,r),init(r-l+2);
    	fp(i,0,mid-l+1) A[i]=D[d][i]; fp(i,0,r-mid) B[i]=D[d+1][i];
    	fill(A+mid-l+2,A+limit,0),fill(B+r-mid+1,B+limit,0);
    	Mul(A,B,D[d],r-l+1),fill(D[d]+r-l+2,D[d]+limit,0);
    }
    int main(){ n=read(),m=read(),rev=qpow(mul(n,m)),prep();
    	fp(i,1,n) a[i]=read(); fp(i,1,m) b[i]=read();
    	solv(a,1,1,n),copy(D[1],D[1]+n+1,f);
    	solv(b,1,1,m),copy(D[1],D[1]+m+1,g);
    	t=read(),qq=max(max(n,m),t); init(qq+1),qq=limit;
    	Ln(f,f+1,qq),Ln(g,g+1,qq),f[0]=n,g[0]=m;
    	fp(i,1,qq-1) f[i]=dec(mod,f[i]),g[i]=dec(mod,g[i]);
    	fac[0]=ifac[0]=ifac[1]=1; fp(i,1,qq-1) fac[i]=mul(fac[i-1],i);
    	fp(i,2,qq-1) ifac[i]=mul(mod-mod/i,ifac[mod%i]);
    	fp(i,1,qq-1) ifac[i]=mul(ifac[i],ifac[i-1]);
    	fp(i,0,qq-1) f[i]=mul(f[i],ifac[i]),g[i]=mul(g[i],ifac[i]);
    	fp(i,qq,qq<<1) f[i]=g[i]=0; init(qq<<1),NTT(f,1),NTT(g,1);
    	fp(i,0,limit-1) f[i]=mul(f[i],g[i]); NTT(f,0);
    	fp(i,1,t) print(mul(f[i],mul(fac[i],rev))); return Ot(),0;
    }
    
  • 相关阅读:
    大的FIbonacci数列_Java求法
    HDU1134_Game of Connections 卡特兰数
    oracle中查询锁表
    SpringBoot之使用Druid连接池以及SQL监控和spring监控
    用vue封装插件并发布到npm
    vue 预览 Excel 表格
    vue + elementUI 表格 底部 合计总数
    springboot项目中实现访问druid内置监控页面
    解决Elementui eltable合计 showsummary不显示,样式混乱问题
    Druid连接池:慢查询监控
  • 原文地址:https://www.cnblogs.com/Judge/p/10748264.html
Copyright © 2011-2022 走看看