xsy1529小Q与进位制 - 分治FFT
Posted dcdcbigbig
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xsy1529小Q与进位制 - 分治FFT相关的知识,希望对你有一定的参考价值。
题意很简单,就是求这个数。。。
其实场上我想出了分治fft的正解。。。然而不会打。。。然后打了个暴力fft挂了。。。
没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂我都没看懂。。。我写的是每三位拆分然后再合并
代码:
1 //强烈谴责卡常数而需要大量优化
2 //upd:还卡精度。。。
3 #include<algorithm>
4 #include<iostream>
5 #include<cstring>
6 #include<cstdio>
7 #include<cmath>
8 #include<queue>
9 #define inf 2147483647
10 #define eps 1e-9
11 using namespace std;
12 typedef long long ll;
13 const double pi=acos(-1);
14 struct complex{
15 double a,b;
16 complex(double _a=0,double _b=0){
17 a=_a;
18 b=_b;
19 }
20 friend complex operator +(complex x,complex y){return complex(x.a+y.a,x.b+y.b);}
21 friend complex operator -(complex x,complex y){return complex(x.a-y.a,x.b-y.b);}
22 friend complex operator *(complex x,complex y){return complex(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);}
23 friend complex operator *(complex x,double y){return complex(x.a*y,x.b*y);}
24 friend complex operator /(complex x,double y){return complex(x.a/y,x.b/y);}
25 };
26 int n,tot=0,bit,bitnum,rev[1000001],tmp[1000001],A[1000001],B[1000001],bs[120001],a[120001];
27 char out[2000001];
28 void fft(complex *s,int op){
29 for(int i=0;i<bit;i++)if(i<rev[i])swap(s[i],s[rev[i]]);
30 for(int i=1;i<bit;i<<=1){
31 complex w(cos(pi/i),op*sin(pi/i));
32 for(int p=i<<1,j=0;j<bit;j+=p){
33 complex wk(1,0);
34 for(int k=j;k<i+j;k++,wk=wk*w){
35 complex x=s[k],y=wk*s[k+i];
36 s[k]=x+y;
37 s[k+i]=x-y;
38 }
39 }
40 }
41 if(op==-1){
42 for(int i=0;i<=bit;i++){
43 s[i]=s[i]/(double)bit;
44 }
45 }
46 }
47 void mul(int a[],int b[],int c[],int n,int m){
48 static complex s1[1000001],s2[1000001];
49 for(bitnum=0,bit=1;bit<=m+n;bit<<=1)bitnum++;
50 for(int i=0;i<bit;i++){
51 rev[i]=(rev[i>>1]>>1)|((i&1)<<(bitnum-1));
52 }
53 for(int i=0;i<n;i++)s1[i].a=a[i],s1[i].b=0;
54 for(int i=0;i<m;i++)s2[i].a=b[i],s2[i].b=0;
55 for(int i=n;i<bit;i++)s1[i].a=s1[i].b=0;
56 for(int i=m;i<bit;i++)s2[i].a=s2[i].b=0;
57 fft(s1,1);
58 fft(s2,1);
59 for(int i=0;i<bit;i++)s1[i]=s1[i]*s2[i];
60 fft(s1,-1);
61 ll p=0;
62 for(int i=0;i<m+n||p;i++){
63 p+=(ll)(s1[i].a+0.5);
64 c[i]=p%1000;
65 p/=1000;
66 }
67 }
68 void add(int a[],int b[],int n){
69 int p=0;
70 for(int i=0;i<n||p;i++){
71 p+=a[i]+b[i];
72 a[i]=p%1000;
73 p/=1000;
74 }
75 }
76 void cdq(int l,int r,int A[],int B[]){
77 if(l==r){
78 A[0]=bs[l]%1000;
79 A[1]=bs[l]/1000%1000;
80 A[2]=bs[l]/1000000;
81 B[0]=a[l]%1000;
82 B[1]=a[l]/1000%1000;
83 B[2]=a[l]/1000000;
84 return;
85 }
86 int mid=(l+r)/2,ll=(mid-l+2)*2,rr=(r-mid+1)*2;
87 cdq(l,mid,A,B);
88 cdq(mid+1,r,A+ll,B+ll);
89 for(int i=0;i<ll;i++)tmp[i]=B[i];
90 mul(A,B+ll,B,ll,rr);
91 add(B,tmp,ll);
92 mul(A,A+ll,A,ll,rr);
93 }
94 void delete_zero(char s[]){
95 int i,j;
96 tot--;
97 for(i=tot;i>=0;i--){
98 if(s[i]!=‘0‘)break;
99 }
100 s[i+1]=0;
101 j=i;
102 for(i=0;i<j;i++,j--)swap(s[i],s[j]);
103 }
104 int main(){
105 scanf("%d",&n);
106 for(int i=1;i<=n;i++){
107 scanf("%d",&bs[i]);
108 }
109 for(int i=1;i<=n;i++){
110 scanf("%d",&a[i]);
111 }
112 cdq(1,n,A,B);
113 //for(int i=0;i<=n<<1;i++)printf("%d ",B[i]);
114 for(int i=0;i<=n<<1;i++){
115 for(int j=0;j<3;j++){
116 out[tot++]=B[i]%10+‘0‘;
117 B[i]/=10;
118 }
119 }
120 //delete_zero(out);
121 int i,j;
122 tot--;
123 for(i=tot;i>=0;i--){
124 if(out[i]!=‘0‘)break;
125 }
126 out[i+1]=0;
127 j=i;
128 for(i=0;i<j;i++,j--)swap(out[i],out[j]);
129 puts(out);
130 return 0;
131 }
以上是关于xsy1529小Q与进位制 - 分治FFT的主要内容,如果未能解决你的问题,请参考以下文章
bzoj4836[Lydsy2017年4月月赛]二元运算 分治+FFT