• 多项式全家桶


    #define lon long long
    #define Dinv(x) Dpow(x,mo-2)	
    #define die(x) memset(x,0,sizeof x)
    
    lon Dpow(lon p,lon q){
    	lon tot=1;
    	while(q){
    		if(q&1)tot=tot*p%mo;
    		p=p*p%mo,q=q>>1;
    	}
    	return tot;
    }
    	
    namespace POLY{
    	#define init(x) const int p7=(x)+10
    	#define bye(s,f,x) rep(i,0,x)s[i]=f[i]
    	
    	const int q7=n7;
    	lon ori1[q7],ori2[q7],rv[q7];
    	
    	lon Dpow(lon p,lon q){
    		lon tot=1;
    		while(q){
    			if(q&1)tot=tot*p%mo;
    			p=p*p%mo,q=q>>1;
    		}
    		return tot;
    	}
    	
    	void Tpre(int n){
    		lon inv=Dinv(3);
    		for(int len=2;len<=n+1;len=len<<1){
    			ori1[len]=Dpow(3,(mo-1)/len);
    			ori2[len]=Dpow(inv,(mo-1)/len);
    		}
    	}
    	
    	void Trev(int n){
    		rep(i,0,n){
    			rv[i]=(rv[i>>1]>>1);
    			if(i&1)rv[i]=rv[i]|((n+1)>>1);
    		}	
    	}
    	
    	int totwo(int x){
    		int z=1;
    		while(z<=x)z=z<<1;
    		return z;
    	}
    	
    	void NTT(lon *f,int n,bool sys){
    		rep(i,0,n){
    			if(i<rv[i])swap(f[i],f[ rv[i] ]);
    		}
    		for(int len=1;len<n+1;len=len<<1){
    			int far=len<<1;
    			lon ori=sys?ori2[far]:ori1[far];
    			for(int i=0;i<=n;i=i+far){
    				lon z=1;
    				rep(j,i,i+len-1){
    					lon tmp=z*f[len+j]%mo;
    					f[len+j]=(f[j]-tmp+mo)%mo;
    					f[j]=(f[j]+tmp)%mo;
    					z=z*ori%mo;
    				}
    			}
    		}
    		if(sys){
    			lon inv=Dinv(n+1);
    			rep(i,0,n)f[i]=f[i]*inv%mo;		
    		}
    	}
    	
    	void Tmul(lon *f,lon *g,int n){
    		Trev(n);
    		NTT(f,n,0),NTT(g,n,0);
    		rep(i,0,n)f[i]=f[i]*g[i]%mo;
    		NTT(f,n,1);
    	}
    	
    	void Tmulz(lon *f,lon *g,lon *S,int n){
    		init(n<<1);lon A[p7],B[p7];
    		die(A),die(B);
    		rep(i,0,n)A[i]=f[i],B[i]=g[i];
    		Trev(n);
    		NTT(A,n,0),NTT(B,n,0);
    		rep(i,0,n)A[i]=A[i]*B[i]%mo;
    		NTT(A,n,1);
    		bye(S,A,n);
    	}
    	
    	void Tinv(lon *f,lon *S,int n){
    		init(n<<1);lon s[p7],A[p7],B[p7];
    		die(A),die(B),die(s);
    		s[0]=Dpow(f[0],mo-2);
    		for(int len=2;len<=n+1;len=len<<1){
    			int far=(len<<1)-1;
    			rep(i,0,len-1)A[i]=f[i],B[i]=s[i];
    			Trev(far);
    			NTT(A,far,0),NTT(B,far,0);
    			rep(i,0,far)s[i]=(B[i]*2%mo-A[i]*B[i]%mo*B[i]%mo+mo)%mo;
    			NTT(s,far,1);
    			rep(i,len,far)s[i]=0;
    		}
    		bye(S,s,n);
    	}
    	
    	void Tderiv(lon *f,lon *S,int n){
    		init(n);lon s[p7];s[n]=0;
    		rep(i,1,n)s[i-1]=f[i]*i%mo;
    		bye(S,s,n);
    	}
    	
    	void Tint(lon *f,lon *S,int n){
    		init(n);lon s[p7];s[0]=0;
    		rep(i,0,n-1)s[i+1]=f[i]*Dpow(i+1,mo-2)%mo;
    		bye(S,s,n);
    	}
    	
    	void Tln(lon *f,lon *S,int n){
    		init(n<<1);lon A[p7],B[p7];
    		die(A),die(B);
    		rep(i,0,n)A[i]=f[i];
    		Tderiv(A,B,n);
    		Tinv(A,A,n);
    		Tmul(A,B,n+n+1);
    		Tint(A,A,n);
    		bye(S,A,n);
    	}
    	
    	void Texp(lon *f,lon *S,int n){
    		init(n<<1);lon s[p7],A[p7],B[p7],C[p7];
    		die(A),die(B),die(C),die(s);
    		s[0]=1;
    		for(int len=2;len<=n+1;len=len<<1){
    			int far=(len<<1)-1;
    			rep(i,0,len-1)A[i]=f[i],B[i]=s[i];
    			Tln(B,C,len-1);
    			rep(i,0,len-1)C[i]=(A[i]-C[i]+mo)%mo;
    			C[0]=(C[0]+1)%mo;
    			Trev(far);
    			NTT(B,far,0),NTT(C,far,0);
    			rep(i,0,far)s[i]=B[i]*C[i]%mo;
    			NTT(s,far,1);
    			rep(i,len,far)s[i]=0;
    		}
    		bye(S,s,n);
    	}
    	
    	void Tsqrt(lon *f,lon *S,int n){
    		init(n<<1);lon s[p7],A[p7],B[p7],C[p7];
    		die(A),die(B),die(C),die(s);
    		s[0]=1;lon inv=Dinv(2);
    		for(int len=1;len<=n+1;len=len<<1){
    			int far=(len<<1)-1;
    			rep(i,0,len-1)A[i]=f[i],B[i]=s[i];
    			Tinv(B,C,len-1);
    			Trev(far);
    			NTT(A,far,0),NTT(C,far,0);
    			rep(i,0,far)s[i]=A[i]*C[i]%mo;
    			NTT(s,far,1);
    			rep(i,0,len-1)s[i]=(s[i]+B[i])%mo*inv%mo;
    			rep(i,len,far)s[i]=0;
    		}
    		bye(S,s,n);
    	}
    	
    	void Tpow(lon *f,lon *S,int n,lon K){
    		init(n<<1);lon s[p7];die(s);
    		Tln(f,s,n);
    		rep(i,0,n)s[i]=s[i]*K%mo;
    		Texp(s,s,n);
    		bye(S,s,n);
    	}	
    	
    	void Tturn(lon *f,int n){
    		rep(i,0,n/2)swap(f[i],f[n-i]);
    	}
    
    	void Tdiv(lon *f,lon *g,lon *S,lon *Syu,int n,int m){
    		init((n+m)<<2);lon A[p7],B[p7],s[p7],sz[p7],syu[p7];
    		die(A),die(B),die(s),die(sz);
    		rep(i,0,n)A[i]=f[i];
    		rep(i,0,m)B[i]=g[i];
    		Tturn(A,n),Tturn(B,m);
    		int z1=totwo(n-m+1)-1;
    		Tinv(B,B,z1);
    		int z2=totwo(n+n-m+1)-1;
    		rep(i,n-m+1,z2)B[i]=0;
    		Tmul(A,B,z2);
    		rep(i,0,n-m)s[i]=A[i];
    		Tturn(s,n-m);
    		rep(i,0,n-m)sz[i]=s[i];
    		int z3=totwo(n+1)-1;
    		rep(i,0,m)B[i]=g[i];
    		rep(i,m+1,z3)B[i]=0;	
    		Tmul(B,s,z3);
    		rep(i,0,m)syu[i]=(f[i]-B[i]+mo)%mo;
    		bye(S,sz,n-m);bye(Syu,syu,m);
    	}
    }
    
  • 相关阅读:
    Node 核心模块HTTP模块
    Node 的 模块 及fs 模块的使用
    Node 简介和环境安装
    RBAC权限管理模型:基本模型及角色模型解析及举例
    JS中Ajax的同步和异步
    tp5.1 获取json对象的json内容
    JavaScript 判断对象中是否有某属性
    php 函数使用可变数量的参数
    ThinkPHP5.1关于查询器查询条件为[NOT] NULL时的写法
    js中const,var,let区别
  • 原文地址:https://www.cnblogs.com/BlankAo/p/14508318.html
Copyright © 2020-2023  润新知