• P5488 差分与前缀和


    P5488 差分与前缀和

    先看前缀和。

    首先有一个显然的递推:

    [sum_{k,i}=sum_{k,i-1}+sum_{k-1,i}\ sum_{0,i}=a_i ]

    按照套路考虑 (a_j)(sum_{k,i}) 的贡献。

    看看这个递推,不就是从 ((0,j)) 走到 ((k,i)) 这个点的方案数吗??直接 (inom{k+i-j}{k}) 即可。

    然后发现挂掉了。。。。。。。

    忽然发现 (sum_{0,i}) 不能转移到 (sum_{0,i+1}) 的!于是少了一步,应该是 (inom{k-1+i-j}{k-1})

    注意这个 (k) 太大了,但是是可以直接 (mod 998244353) 的。然后递推 (p_i=inom{k+i}{k}) 即可。

    发现 (a*p) 就是答案了。

    再考虑差分。

    之前见过一点生成函数内容。 (k) 阶差分就是乘上 ((1-x)^k) ,这东西二项式系数就是 ((-1)^iinom{k}{i})

    递推预处理 (p_i=(-1)^iinom{k}{i})(a*p) 就是答案了。

    const int N=100005;
    const int M=N<<2;
    #define mod 1004535809
    void fmod(int&x){x+=x>>31&mod,x-=mod,x+=x>>31&mod;}
    int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
    inline int exread(){
    	int x=0;char ch=getchar();
    	while(!isdigit(ch))ch=getchar();
    	while(isdigit(ch))x=(1ll*x*10+ch-'0')%mod,ch=getchar();
    	return x;
    }
    
    int rev[M],lg,lim;
    void init(const int&n){
    	for(lg=0,lim=1;lim<=n;lim<<=1,++lg);
    	for(int i=0;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
    }
    void NTT(int*a,int op){
    	int g=op?3:qpow(3,mod-2);
    	for(int i=0;i<lim;++i)if(i>rev[i])swap(a[i],a[rev[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=qpow(g,(mod-1)/(i<<1));
    		for(int j=0;j<lim;j+=i<<1){
    			int w0=1;
    			for(int k=0;k<i;++k,w0=1ll*w0*wn%mod){
    				const int X=a[j+k],Y=1ll*w0*a[i+j+k]%mod;
    				fmod(a[j+k]=X+Y),fmod(a[i+j+k]=X-Y+mod);
    			}
    		}
    	}
    	if(op)return;int ilim=qpow(lim,mod-2);
    	for(int i=0;i<lim;++i)a[i]=1ll*ilim*a[i]%mod;
    }
    
    int n,k,t,a[M],f[M];
    namespace solve1{
    signed main(){
    	f[0]=1;for(int i=1;i<n;++i)f[i]=1ll*f[i-1]*(k+i-1)%mod*qpow(i,mod-2)%mod;
    	init(n<<1),NTT(a,1),NTT(f,1);
    	for(int i=0;i<lim;++i)f[i]=1ll*a[i]*f[i]%mod;
    	NTT(f,0);
    	for(int i=0;i<n;++i)fmod(f[i]),printf("%d ",f[i]);
    	return 0;
    }
    
    }
    namespace solve2{
    signed main(){
    	f[0]=1;for(int i=1;i<n;++i)f[i]=-1ll*f[i-1]*(k-i+1)%mod*qpow(i,mod-2)%mod;
    	init(n<<1),NTT(a,1),NTT(f,1);
    	for(int i=0;i<lim;++i)f[i]=1ll*a[i]*f[i]%mod;
    	NTT(f,0);
    	for(int i=0;i<n;++i)fmod(f[i]),printf("%d ",f[i]);
    	return 0;
    }
    }
    signed main(){
    	n=read(),k=exread(),t=read();
    	for(int i=0;i<n;++i)a[i]=read();
    	if(!t)solve1::main();else solve2::main();
    	return 0;
    }
    

    大概是我人傻常数大的缘故,不知道为啥别人跑的这么快。。。

  • 相关阅读:
    java.io.file
    连线小游戏
    发票类型区分的正则表达式(仅区分普票专票)
    mybatis: No enum constant org.apache.ibatis.type.JdbcType."VARCHAR"
    bootstrap inputfile 使用-上传,回显
    微积分极限中一例
    oracle 查看表结构语句
    redis无法连接
    项目配置shiro原缓存注解失效
    bug 找不到或无法加载主类main.java.*
  • 原文地址:https://www.cnblogs.com/zzctommy/p/14191414.html
Copyright © 2020-2023  润新知