• BZOJ 3992: [SDOI2015]序列统计


    NTT模板题

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring> 
    #define ll long long
    using namespace std;
    const int N=20000;
    const int mod=1004535809;
    int L,M,n,m,x,s,w,len,lenf,X,vis[N],rev[N];
    ll h[N],a[N],b[N],q[N];
    ll pow(ll a,ll b,ll mod){
    	a%=mod;
    	ll ans=1;
    	while (b){
    		if (b&1) ans=ans*a%mod;
    		a=a*a%mod;
    		b=b>>1;
    	}
    	return ans;
    }
    int calc_w(int x){
    	if (x==2) return 1;
    	for (int i=2; i; i++){
    		int flag=1;
    		for (int j=2; j*j<x; j++)
    			if (pow(i,(x-1)/j,x)==1){
    				flag=0;
    				break;
    			}
    		if (flag) return i;
    	}
    }
    void NTT(ll *a,int n,int opt){
        for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
    	for (int i=1; i<n; i<<=1){
    		ll wn=pow(3,(mod-1)/(i<<1),mod);
    		for (int j=0; j<n; j+=(i<<1)){
    			ll w=1;
    			for (int k=0; k<i; k++,w=w*wn%mod){
    				ll x=a[j+k],y=w*a[j+k+i]%mod;
    				a[j+k]=(x+y)%mod,a[j+k+i]=(x-y+mod)%mod;
    			}
    		}
    	}
    	if (opt==-1) reverse(a+1,a+n);
    }
    void mul(ll h[N],ll q[N]){
    	for (int i=0; i<len; i++) a[i]=h[i]%mod;
    	for (int i=0; i<len; i++) b[i]=q[i]%mod;
    	NTT(a,len,1); 
    	NTT(b,len,1);		
    	for (int i=0; i<len; i++) a[i]=a[i]*b[i]%mod;
    	NTT(a,len,-1);
    	ll inv=pow(len,mod-2,mod);
    	for (int i=0; i<len; i++) a[i]=a[i]*inv%mod;
    	for (int i=0; i<lenf; i++) h[i]=(a[i]+a[i+lenf])%mod;
    }
    void solve(int x){
    	h[0]=1;
    	while (x){
    		if (x&1) mul(h,q);
    		x>>=1;
    		mul(q,q);
    	}
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&X,&s);
    	w=calc_w(m);
    	for (int i=1; i<=s; i++){
    		int x;
    		scanf("%d",&x);
    		vis[x]=1;
    	}
    	int pos=-1;
    	for (int i=0,j=1; i<m-1; i++,j=j*w%m){
    		if (vis[j]) q[i]=1;
    		if (j==X) pos=i;
    	}
    	lenf=m-1;
    	M=lenf*2,len=1,L=0;
    	while (len<=M) len<<=1,L++;
    	for (int i=0; i<len; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
    	solve(n);
    	if (pos!=-1) printf("%lld
    ",h[pos]);
    	else printf("0
    ");
    	return 0;
    }
    

      

  • 相关阅读:
    DataInputStream与DataOutputStream类
    BluetoothChat例程分析
    Android中的Handler机制
    我的IT之路2012(二)
    菜鸟学Java(二)——Filter解决中文乱码问题
    菜鸟学Java(一)——Ajax异步检查用户名是否存在
    FTP文件操作之创建目录
    FTP文件操作之获取文件列表
    使用powershell计算性能计数器的均值
    收缩临时库 shrink tempdb
  • 原文地址:https://www.cnblogs.com/silenty/p/10319213.html
Copyright © 2020-2023  润新知