小菜鸡 NTT 求助
查看原帖
小菜鸡 NTT 求助
35891
huangzirui楼主2020/9/28 21:29

话说这题不能用 NTT 吗QAQ

#include <bits/stdc++.h>
#define ll long long
#define Mid ((L+R)>>1)
using namespace std;
typedef pair<int,int> pii;
inline int read(){
	char c;int x=0;int b=1;do{c=getchar();if(c==45)b=-1;}while(c>57||c<48);
	do x=x*10+c-48,c=getchar();while(c<=57&&c>=48);x*=b;return x;
}
const int maxn=400010,mod=998244353,P=3;
int i,j,k,n,m,is_prime[maxn],prime[maxn],cnt;
ll A[5][maxn];
void init(){
	is_prime[1]=1;
	for(int i=2;i<maxn;i++)is_prime[i]=1;
	for(int i=2;i<maxn;i++){
		if(is_prime[i])prime[++cnt]=i;
		for(int j=1;j<=cnt && i*prime[j]<maxn;j++){
			is_prime[i*prime[j]]=0;
			if(i%prime[j]==0)break;
		}
	}
}
int R[maxn];ll tmp[maxn];
ll ksm(ll sum,int num){
	ll ans=1;
	while(num){
		if(num&1)ans=ans*sum%mod;
		sum=sum*sum%mod;
		num>>=1;
	}return ans;
}
void NTT(int len,ll *a,bool op){
	for(int i=0;i<len;i++)tmp[R[i]]=a[i];
	for(int i=0;i<len;i++)a[i]=tmp[i];
	ll Wn,w,P2=ksm(P,mod-2);
	for(int i=1;i<len;i*=2){
		Wn=ksm((op? P:P2),(mod-1)/(i*2));
		for(int j=0;j<len;j+=i*2){
			w=1;
			for(int k=0;k<i;k++,w=w*Wn%mod){
				int K=k+j;
				ll S1=a[K],S2=a[K+i]*w%mod;
				a[K]=(S1+S2)%mod;
				a[K+i]=(S1-S2+mod)%mod;
			}
		}
	}
}
void mul(int N,ll *a,ll *b){
	int len=1,L=0;
	while(len<=N*2)len*=2,L++;
	for(int i=0;i<len;i++)R[i]=R[i/2]/2+((i&1)*(1<<L-1));
	NTT(len,a,1);NTT(len,b,1);
	for(int i=0;i<len;i++)a[i]=a[i]*b[i]%mod;
	NTT(len,a,0);
	for(int i=0;i<len;i++)a[i]=a[i]*ksm(len,mod-2)%mod;
}
void init2(int l,int r){
	for(int i=l;i<=r;i++)
		if(!is_prime[i])
			for(int j=1;j<=4;j++)A[j][i]=1;
}map<char,int>M;
string s;
int main() {
	freopen("UVA12298.in","r",stdin);
	freopen("UVA12298.out","w",stdout);
	init();
	M['S']=1;M['H']=2;
	M['C']=3;M['D']=4;
	int l=0,r=0;
	while(cin>>l>>r>>n){
		if(!l)return 0;
		init2(1,r);
		for(i=1;i<=n;i++){
			cin>>s;
			A[M[s[1]]][s[0]-'0']=0;
		}
		/*
		for(i=0;i<=r;i++)cout<<A[1][i]<<' ';cout<<endl;
		for(i=0;i<=r;i++)cout<<A[2][i]<<' ';cout<<endl;
		for(i=0;i<=r;i++)cout<<A[3][i]<<' ';cout<<endl;
		for(i=0;i<=r;i++)cout<<A[4][i]<<' ';cout<<endl;
		*/
		mul(r,A[1],A[2]);
		mul(r,A[3],A[4]);
		mul(2*r,A[1],A[3]);
		for(i=l;i<=r;i++)
			printf("%lld\n",A[1][i]);
		for(i=0;i<maxn;i++)
			A[1][i]=A[2][i]=A[3][i]=A[4][i]=0;
		if(l)puts("");
	}
	//cerr << 1.0*clock()/CLOCKS_PER_SEC << endl;
	return 0;
}

2020/9/28 21:29
加载中...