zoukankan      html  css  js  c++  java
  • P5488 差分与前缀和 生成函数+多项式EXP

    题意:

    戳这里

    分析:

    • 前置芝士 : 生成函数 多项式EXP

    将题目拆成两问:

    1. 前缀和

      一次前缀和操作 (sum_{j<i}a_j o a_i) 等价于将 (a) 序列的 OGF 乘了一个 (1+x+x^2+x^3dots x^n)(frac{1}{1-x})(ans=a * frac{1}{(1-x)^k})

    2. 差分

      同理,一次差分操作 (a_i-a_{i-1} o a_{i-1}) 等价于将序列的 OGF 乘了一个 ((1-x)) (ans=a * (1-x)^k)

    直接上多项式 EXP

    代码:

    #include<bits/stdc++.h>
    #define inl inline 
    #define reg register 
    
    using namespace std;
    
    namespace zzc
    {
        typedef long long ll;
        const int maxn = 3e5+5;
        const long long mod = 1004535809;
        inl ll read()
        {
            ll x=0,f=1;char ch=getchar();
            while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
            while(isdigit(ch)){x=(x*10+ch-48)%mod;ch=getchar();}
            return x*f;
        }
    
        ll n,k,t,l,lim;
        ll a[maxn],b[maxn],c[maxn],d[maxn],e[maxn],f[maxn],g[maxn],h[maxn],rev[maxn];
        
        ll qpow(ll x,ll y)
        {
        	ll res=1;
        	while(y)
        	{
        		if(y&1) res=res*x%mod;
        		x=x*x%mod;
        		y>>=1;
        	}
        	return res;
        }
        
        void ntt(ll *a,ll inv)
        {
    		for(ll i=0;i<lim;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
    		for(ll len=1;len<lim;len<<=1)
    		{
    			ll w1=qpow(inv==1?3:1004535810/3,(mod-1)/(len<<1));
    			for(ll i=0;i<lim;i+=(len<<1))
    			{
    				ll w=1;
    				for(ll j=0;j<len;j++)
    				{
    					ll x=a[i+j],y=w*a[i+j+len]%mod;
    					a[i+j]=(x+y)%mod;
    					a[i+j+len]=(x-y+mod)%mod;
    					w=w*w1%mod;
    				}
    			}
    		}
    		if(inv==1) return ;
    		long long tmp=qpow(lim,mod-2);
    		for(int i=0;i<lim;i++) a[i]=(a[i]*tmp%mod+mod)%mod;
        }
        
    
    	void get_len(int k)
    	{
    		lim=1,l=0;
    		while(lim<(k<<1)) lim<<=1,l++;
    		for(ll i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    	}
    	
    	void get_inv(ll *f,ll *g,ll k)
    	{
    		if(k==1)
    		{
    			g[0]=qpow(f[0],mod-2);
    			return ;
    		}
    		get_inv(f,g,(k+1)>>1);
    		get_len(k);
    		for(ll i=0;i<k;i++) c[i]=f[i];
    		for(ll i=k;i<lim;i++) c[i]=0;
    		ntt(c,1);ntt(g,1);
    		for(ll i=0;i<lim;i++) g[i]=((2ll-c[i]*g[i]%mod+mod)%mod)*g[i]%mod;
    		ntt(g,-1);
    		for(ll i=k;i<lim;i++) g[i]=0;
    	}
    	
    	void get_der(ll *f,ll *g,ll k)
    	{
    		for(ll i=1;i<k;i++) g[i-1]=i*f[i]%mod;
    		g[k-1]=0;
    	}
    	
    	void get_int(ll *f,ll *g,ll k)
    	{
    		for(ll i=1;i<k;i++) g[i]=f[i-1]*qpow(i,mod-2)%mod;
    		g[0]=0;
    	}
    	
    	void get_ln(ll *f,ll *g,ll k)
    	{
    		memset(a,0,sizeof(a));
    		memset(b,0,sizeof(b));
    		get_der(f,a,k);get_inv(f,b,k);get_len(k);
    		ntt(a,1);ntt(b,1);
    		for(ll i=0;i<lim;i++) a[i]=a[i]*b[i]%mod;
    		ntt(a,-1);
    		get_int(a,g,k); 
    	}	
        
        void get_exp(ll *a,ll *b,ll k)
        {
        	if(k==1)
        	{
        		b[0]=1;
        		return ;
        	}
        	get_len(k);
        	get_exp(a,b,(k+1)>>1);get_ln(b,d,k);
        	for(ll i=0;i<k;i++) e[i]=a[i];
        	for(ll i=k;i<lim;i++) e[i]=d[i]=0;
        	ntt(d,1);ntt(e,1);ntt(b,1);
        	for(ll i=0;i<lim;i++) b[i]=(1-d[i]+e[i]+mod)%mod*b[i]%mod;
        	ntt(b,-1);
        	for(ll i=k;i<lim;i++) b[i]=0;
        }
        
        void work()
        {
        	n=read();k=read();t=read();
        	for(int i=0;i<n;i++) f[i]=read();
        	g[0]=1;g[1]=mod-1;
        	get_ln(g,h,n);
        	for(ll i=0;i<n;i++) h[i]=h[i]*k%mod;
        	memset(g,0,sizeof(g));
        	get_exp(h,g,n);
        	if(!t)
        	{
        		memset(h,0,sizeof(h));
        		get_inv(g,h,n);
        		memcpy(g,h,sizeof(h));
        	}
        	get_len(n);
        	ntt(f,1);ntt(g,1);
        	for(ll i=0;i<lim;i++) f[i]=f[i]*g[i]%mod;
        	ntt(f,-1);
        	for(ll i=0;i<n;i++) printf("%lld ",f[i]);
        }
        
    
    }
    
    int main()
    {
        zzc::work();
        return 0;
    }
    
  • 相关阅读:
    【Demo 0062】文件遍历
    【Demo 0068】获取分区信息
    【Demo 0060】记录个人信息
    【Demo 0069】文件读写
    【Demo 0064】监控文件/目录变更
    【Demo 0067】文件类型关联图标
    【Demo 0065】获取被修改的文件/目录
    【Demo 0062】目录及文件基本操作
    【Demo 0061】打开与保存文件
    【Demo 0066】监控被变更文件/目录(完成端口)
  • 原文地址:https://www.cnblogs.com/youth518/p/14317409.html
Copyright © 2011-2022 走看看