[生成函数][DFT][NTT] Hdu P6067 Big Integer

Posted comfortable

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[生成函数][DFT][NTT] Hdu P6067 Big Integer相关的知识,希望对你有一定的参考价值。

技术图片

 

 

 题解

技术图片

技术图片

 

代码

 1 #include <cstdio>
 2 #include <istream>
 3 #define ll long long
 4 using namespace std;
 5 const ll N=200010,mo=786433;
 6 int T,n,m,k,x,y,sum,num[N],f[N],len,L,rev[N],v[10][N];
 7 ll a[10][N],inv[mo],fac[N],ny[N],ans[N],p[N],P[N];
 8 char s[N];
 9 ll ksm(ll a,ll b)  ll r=1; for (;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r; 
10 void ntt(ll *a,int len,int f)
11 
12     for (int i=0;i<len;i++) if (rev[i]>i) swap(a[i],a[rev[i]]);
13     for (int i=2;i<=len;i<<=1)
14     
15         ll r,m=i>>1;
16         if (f==1) r=p[i]; else r=P[i];
17         for (int j=0;j<len;j+=i)
18         
19             ll R=1;
20             for (int k=0;k<m;k++,R=R*r%mo)
21             
22                 ll x=a[j+k],y=a[j+k+m]*R%mo;
23                 a[j+k]=(x+y)%mo,a[j+k+m]=(x-y+mo)%mo;
24             
25         
26     
27     if (f==-1)  ll r=ksm(len,mo-2); for (int i=0;i<len;i++) a[i]=a[i]*r%mo; 
28 
29 int main()
30 
31     
32     fac[0]=ny[0]=1;
33     for (int i=1;i<N;i++) p[i]=ksm(10,(mo-1)/i),P[i]=ksm(p[i],mo-2);
34     for (int i=0;i<mo;i++) inv[i]=ksm(i,mo-2);
35     for (int i=1;i<N;i++) fac[i]=fac[i-1]*(ll)i%mo;
36     ny[N-1]=ksm(fac[N-1],mo-2);
37     for (int i=N-2;i;i--) ny[i]=ny[i+1]*(ll)(i+1)%mo;
38     scanf("%d",&T);
39     while (T--) 
40     
41         scanf("%d%d%d",&n,&m,&k),n--,sum=0;
42         for (int i=0;i<n;i++) 
43         
44             scanf("%s",s);
45             for (int j=0;j<=m;j++) v[i][j]=s[j]-0;
46         
47         for (len=1,L=-1;len<=n*m;len*=2) L++;
48         for (int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
49         for (int i=0;i<len;i++) num[i]=0,f[i]=1;
50         for (int i=0;i<n;i++) 
51         
52             for (int j=0;j<len;j++) a[i][j]=0;
53             for (int j=0;j<=m;j++) if (v[i][j]) a[i][j]=ny[j];
54             ntt(a[i],len,1); 
55             for (int j=0;j<len;j++) if (a[i][j]) f[j]=f[j]*a[i][j]%mo; else num[j]++;
56         
57         for (int i=0;i<len;i++) ans[i]=num[i]?0:f[i];
58         for (int x,y;k;k--)
59         
60             scanf("%d%d",&x,&y),x--;
61             for (int i=0;i<len;i++) if (a[x][i]) f[i]=f[i]*inv[a[x][i]]%mo; else num[i]--;
62             ll flag;
63             if (v[x][y]==1) flag=-1; else flag=1;
64             v[x][y]^=1;
65             ll r=1,R=ksm(p[len],y);
66             for (int i=0;i<len;i++,r=r*R%mo) a[x][i]=(a[x][i]+flag*inv[fac[y]]*r%mo+mo)%mo;
67             for (int i=0;i<len;i++) if (a[x][i]) f[i]=f[i]*a[x][i]%mo; else num[i]++;
68             for (int i=0;i<len;i++) ans[i]=(ans[i]+(num[i]?0:f[i]))%mo;
69         
70         ntt(ans,len,-1);
71         for (int i=1;i<len;i++) sum=(sum+ans[i]*fac[i]%mo)%mo;
72         printf("%lld\\n",sum);
73     
74 

 

以上是关于[生成函数][DFT][NTT] Hdu P6067 Big Integer的主要内容,如果未能解决你的问题,请参考以下文章

模板篇NTT和三模数NTT

HDU-4609(FFT/NTT)

HDU-5332(前缀和优化dp/CDQ+NTT)

HDU5322 Hope(DP + CDQ分治 + NTT)

HDU-6036 Division Game(ntt模板)

luoguP5644 [PKUWC2018]猎人杀 概率期望+生成函数+NTT