Question: given n (n<=10^9), prime number M (3<=m<=8000), 1<=x=m, and a set of [0,m-1] intervals, how many series of n is satisfied that each element belongs to the set S and the product of all elements mod m =x
Find the root, take an indicator of each element in the S set, and then generate the generating function f (x)
So the answer is (f (x)) ^n (mod x^ (m-1), mod 1004535809)
On the NTT with a polynomial quick power to do it.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 16400# Define MOD 1004535809#define INF 0x3f3f3f3f#define G 3using namespace Std;int n,m,d,x,s;int ind[m];long long Quick_power (l Ong long X,int y,int p) {Long long re=1;while (y) {if (y&1) (re*=x)%=p; (x*=x)%=p; y>>=1;} return re;} void NTT (int a[],int n,int type) {static int temp[m];int i;if (n==1) return; for (i=0;i<n;i+=2) temp[i>>1]=a[i], temp[i+n>>1]=a[i+1];memcpy (A,temp,sizeof (a[0]) *n); int *l=a,*r=a+ (n>>1); NTT (L,n>>1,type); NTT (R,n>>1,type); Long long W=quick_power (G, (Long Long) type* (MOD-1)/n% (MOD-1), MOD), Wn=1;for (i=0;i<n> >1;i++, (wn*=w)%=mod) temp[i]= (L[i]+wn*r[i])%mod,temp[i+ (n>>1)]= (l[i]-wn*r[i]%mod+mod)%MOD;memcpy (A, Temp,sizeof (A[0]) *n);} struct Gf{int a[m]; GF () {}GF (bool) {memset (a,0,sizeof a); a[0]=1;} int& operator [] (int x) {return a[x];} gf& operator *= (const GF &f) {static int b[m];int i;memcpy (b,f.a,sizeof b); NTT (A,d,1); NTT (b,d,1); for (i=0;i<d;i++) a[i]= (long Long) a[i]*b[i]%mod; NTT (a,d,mod-2); for (i=m-1;i<=m-2<<1;i++) (a[i-(m-1)]+=a[i])%=mod,a[i]=0;long long Inv=quick_power (d,MOD-2 , MOD); for (i=0;i<=m-2;i++) A[i]=a[i]*inv%mod;return *this;}} A;int Get_primitive_root () {static int stack[m],top;int i,j,temp=m-1;for (i=2;i<=temp;i++) if (temp%i==0) {stack[++ Top]=i;while (temp%i==0) temp/=i;} for (i=2;; i++) {for (j=1;j<=top;j++) if (Quick_power (i, (m-1)/stack[j],m) ==1) break;if (j==top+1) return i;}} GF Quick_power (gf &x,int y) {gf Re (true), while (y) {if (y&1) re*=x;x*=x; y>>=1;} return re;} int main () {int i,x;cin>>n>>m>>x>>s;for (d=1;d<=m+m;d<<=1); int g=get_primitive_ Root (); for (i=0,x=1;i<m-1;i++, (x*=g)%=m) ind[x]=i;for (i=1;i<=s;i++) {scanf ("%d", &x); if (!x) continue;a[ Ind[x]]=1;} GF Ans=quick_power (a,n); Cout<<ans[ind[x]]<<endl;return 0;}
Bzoj 3992 Sdoi2015 Sequence Statistics fast number theory transformation