Codechef Devu and Locks(FFT)

枚舉10amodP10^a\bmod P的值,求出有多少aa滿足條件。
然後就是愉快的FFTFFT了。
AC Code\mathcal AC \ Code

#include<bits/stdc++.h>
#define maxn 40005
#define mod 998244353
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
using namespace std;

int n,P,m,cnt[55];
int Wl,Wl2,w[maxn]={1},lg[maxn],inv[maxn]={1,1};
int Pow(int b,int k){ int r=1;for(;k;k>>=1,b=1ll*b*b%mod) if(k&1) r=1ll*r*b%mod; return r; }
void init(int n){
	for(Wl=1;n>=Wl<<1;Wl<<=1);w[1]=Pow(3,(mod-1)/(Wl2=Wl<<1));
	rep(i,2,Wl2) w[i]=1ll*w[i-1]*w[1]%mod,inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod,lg[i]=lg[i>>1]+1;
}
void NTT(int *A,int n,int tp){
	static int r[maxn];
	rep(i,1,n-1) i<(r[i]=(r[i>>1]>>1)|(i&1)<<lg[n]-1) && (swap(A[i],A[r[i]]),0);
	for(int L=1,B=Wl;L<n;L<<=1,B>>=1) for(int s=0;s<n;s+=L<<1) for(int k=s,x=0,t;k<s+L;k++,x+=B)
		t=1ll*w[tp^1?Wl2-x:x]*A[k+L] % mod,A[k+L]=(A[k]-t)%mod,A[k]=(A[k]+t)%mod;
	if(tp^1) rep(i,0,n-1) A[i]=1ll*A[i]*inv[n]%mod;
}
void MUL(int *A,int *B,int *C,int n,int m){
	static int st[2][maxn];
	int L = 1 << lg[n+m] + 1;
	rep(i,0,L-1) st[0][i] = i <= n ? A[i] : 0 ,
		st[1][i] = i <= m ? B[i] : 0;
	NTT(st[0],L,1),NTT(st[1],L,1);
	rep(i,0,L-1) C[i] = 1ll * st[0][i] * st[1][i] % mod;
	NTT(C,L,-1);
}
int F[maxn],R[maxn],G[55][maxn],H[55][maxn],T[55][maxn];

struct mat{
	int a[105][105];
	mat (int d=0){ memset(a,0,sizeof a);for(int i=0;i<P;i++) a[i][i]=d; }
	mat operator *(const mat &B)const{
		mat r;
		for(int i=0;i<2*P;i++) for(int j=0;j<2*P;j++) for(int k=0;k<2*P;k++)
			r.a[i][k] = (r.a[i][k] + a[i][j] * B.a[j][k]);
		return r;
	}
}A;

mat Pow(mat b,int k){
	mat r(1);
	for(;k;k>>=1,b=b*b)
		if(k&1)
			r=r*b;
	return r;
}

int main(){
	scanf("%d%d%d",&n,&P,&m);
	init(m<<1);
	G[0][0] = 1;
	for(int i=0;i<P;i++)
		A.a[i][i*10ll%P] ++,
		A.a[i][i+P] ++ ,
		A.a[i+P][i+P]++;
	A = Pow(A , n);
	for(int i=0;i<P;i++)
		cnt[i] = A.a[1][i+P];
	if(P == 1) cnt[0] = n;
	for(int i=0;i<P;i++) if(cnt[i]){
		int K=cnt[i];
		memset(F,0,sizeof F);
		memset(R,0,sizeof R);
		R[0] = 1;
		for(int j=0;j<=min(m,9);j++) F[j] = 1;
		for(;K;K>>=1,MUL(F,F,F,m,m)) if(K&1) MUL(F,R,R,m,m);
		int L = 1 << lg[2 * m] + 1;
		memset(T,0,sizeof T);
		memset(H,0,sizeof H);
		for(int j=0;j<=m;j++) T[j * i % P][j] = R[j];
		for(int j=0;j<P;j++) NTT(T[j],L,1),NTT(G[j],L,1);
		for(int j=0;j<P;j++) for(int k=0;k<P;k++)
			for(int u=0;u<L;u++)
				H[(j+k)%P][u] = (H[(j+k)%P][u] + 1ll * T[j][u] * G[k][u]) % mod;
		for(int j=0;j<P;j++){
			NTT(H[j],L,-1);
			for(int k=0;k<L;k++)
				G[j][k] = k <= m ? H[j][k] : 0;
		}
	}
	for(int i=0;i<=m;i++){
		if(i) G[0][i] = (G[0][i] + G[0][i-1]) % mod; 
		printf("%d%c",(G[0][i]+mod)%mod," \n"[i==m]);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章