zoukankan      html  css  js  c++  java
  • 【CF932E】Perpetual Subtraction(NTT,线性代数)

    【CF932E】Perpetual Subtraction(NTT,线性代数)

    题面

    洛谷
    CF

    题解

    (f_{i,j})表示(i)轮之后这个数恰好为(j)的概率。
    得到转移:(displaystyle f_{i,j}=sum_{k=j}^{n}f_{i-1,k}*frac{1}{k+1})
    看成生成函数就有(displaystyle F_i(x)=sum_{j=0}^{n}x^jsum_{kge j}frac{f_{i-1,k}}{k+1})
    把两维换过来就是(displaystyle sum_{k=0}^{n}frac{f_{i-1,k}}{k+1}sum_{j=0}^k x^j=sum_{k=0}^nfrac{f_{i-1,k}}{k+1}frac{x^{k+1}-1}{x-1}=frac{1}{x-1}sum_{k=0}^nfrac{f_{i-1,k}}{k+1}(x^{k+1}-1))
    (frac{1}{k+1})这个东西非常让人不爽,恰好发现后面有(x^{k+1},那么我们求导再积分)
    (displaystyle F_i(x)=frac{1}{x-1}int_{1}^x sum_{k=0}^n f_{i-1,k}t^kdt=frac{1}{x-1}int_{1}^xF_{i-1}(t)dt)
    (displaystyle G_i(x)=F_{i}(x+1)=frac{1}{x}int_{1}^{x+1}F_{i-1}(t)dt)
    进一步有:(displaystyle G_i(x)=frac{1}{x}int_{0}^xG_{i-1}(t)dt=sum_{j}frac{g_{i-1,j}}{j+1}x^j)
    那么,再把(G(x))拆开,我们可以得到:(g_{i,j}=frac{g_{i-1,j}}{j+1}),所以可以知道(g_{m,j}=frac{g_{0,j}}{(j+1)^m})
    然后考虑(g)怎么求。
    有:(displaystyle sum_{i}g_ix^i=sum_{i}f_i(x+1)^i=sum_{i}f_isum_{j}{ichoose j}x^j)
    所以有(displaystyle g_i=sum_{jge i}{jchoose i}f_j),二项式反演有(displaystyle f_i=sum_{jge i}(-1)^{j-i}{jchoose i}g_j)
    那么先用(f_{0,j})求出(g_{0,j}),乘上(frac{1}{(j-1)^m})之后再卷积算回去就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define ll long long
    #define MOD 998244353
    #define MAX 280280
    inline ll read()
    {
    	ll 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 len,int opt)
    {
    	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 p=i<<1,j=0;j<N;j+=p)
    			for(int k=0;k<i;++k)
    			{
    				int X=P[j+k],Y=1ll*P[i+j+k]*W[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,a[MAX],b[MAX],jc[MAX],jv[MAX],inv[MAX];
    int main()
    {
    	n=read();m=read()%(MOD-1);int N;for(N=1;N<=n+n;N<<=1);
    	for(int i=0;i<=n;++i)a[i]=read();
    	jc[0]=jv[0]=inv[0]=inv[1]=1;
    	for(int i=2;i<=n+1;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
    	for(int i=1;i<=n+1;++i)jc[i]=1ll*jc[i-1]*i%MOD;
    	for(int i=1;i<=n+1;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;
    	for(int i=0;i<=n;++i)a[i]=1ll*a[i]*jc[i]%MOD,b[i]=jv[i];
    	reverse(&a[0],&a[n+1]);
    	NTT(a,N,1);NTT(b,N,1);
    	for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%MOD;
    	NTT(a,N,-1);
    	for(int i=0;i<=n;++i)a[i]=1ll*a[i]*fpow(inv[n-i+1],m)%MOD*((i&1)?MOD-1:1)%MOD;
    	for(int i=n+1;i<N;++i)a[i]=0;
    	NTT(a,N,1);
    	for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%MOD;
    	NTT(a,N,-1);
    	for(int i=0;i<=n;++i)a[i]=1ll*a[i]*((i&1)?MOD-1:1)%MOD*jv[n-i]%MOD;
    	reverse(&a[0],&a[n+1]);
    	for(int i=0;i<=n;++i)printf("%d ",a[i]);puts("");
    	return 0;
    }
    
  • 相关阅读:
    100个精彩的开源游戏
    poj 2104 K-th Number
    Redis源代码分析-内存数据结构intset
    android音乐播放器开发 SweetMusicPlayer 实现思路
    MySQL 二进制日志(Binary Log)
    Node.js 博客实例(六)留言功能
    HBase总结(十二)Java API 与HBase交互实例
    window+Apache 配置虚拟主机(2)
    Web Service那点事
    JSP基本语法
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10745679.html
Copyright © 2011-2022 走看看