zoukankan      html  css  js  c++  java
  • FFT

      1 #include<cstdio> 
      2 #include<cstring>
      3 #include<cmath>
      4 #include<ctime>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<stack>
      9 #include<set>
     10 #define esp (1e-8)
     11 #define maxint (2147483647)
     12 #define pi (3.141592653589793)
     13 #define l(a) ((a)<<1)
     14 #define r(a) ((a)<<1|1)
     15 #define b(a) (1<<(a))
     16 #define rep(i,a,b) for(int i=a;i<=(b);i++)
     17 #define clr(a) memset(a,0,sizeof(a))
     18 typedef long long ll;
     19 using namespace std;
     20 int readint(){
     21     int t=0,f=1;char c=getchar();
     22     while(!isdigit(c)){
     23         if(c=='-') f=-1;
     24         c=getchar();
     25     }
     26     while(isdigit(c)){
     27         t=(t<<3)+(t<<1)+c-'0';
     28         c=getchar();
     29     }
     30     return t*f;
     31 }
     32 ll readll(){
     33     ll t=0ll,f=1ll;char c=getchar();
     34     while(!isdigit(c)){
     35         if(c=='-') f=-1ll;
     36         c=getchar();
     37     }
     38     while(isdigit(c)){
     39         t=(t<<3ll)+(t<<1ll)+ll(c-'0');
     40         c=getchar();
     41     }
     42     return t*f;
     43 }
     44 const int maxk=100,maxn=500009;
     45 int n,m,cnt=0;
     46 struct complex{
     47     double r,i;
     48     inline complex(double R,double I){
     49         r=R;i=I;
     50     }
     51     inline complex(){}
     52     inline void out(){
     53         if(abs(i)>esp) printf("%.2lf %.2lfi
    ",r,i);
     54         else printf("%.2lf
    ",r);
     55     }
     56     inline complex operator +(const complex A)const{
     57         return complex(r+A.r,i+A.i);
     58     }
     59     inline complex operator -(const complex A)const{
     60         return complex(r-A.r,i-A.i);
     61     }
     62     inline complex operator *(const complex A)const{
     63         return complex(r*A.r-i*A.i,i*A.r+r*A.i);
     64     }
     65 }pool[maxk][maxn],*S[maxk];
     66 complex*newarray(){
     67     return S[--cnt];
     68 }
     69 int rev(int t){//将t化为2^k 
     70     int T=0;
     71     for(T=0;b(T)<t;T++);
     72     return b(T);
     73 }
     74 complex*FFT(complex a[],int t,int opt){//t为2的整数次幂 opt==1->FFT opt==-1->逆FFT
     75     if(t==1) return a;
     76     complex w=complex(1,0),w1=complex(cos(2*pi/t),sin(2*pi/t*opt));//只需在sin中乘上opt 
     77     complex*y=newarray(),*a0=newarray(),*a1=newarray();
     78     rep(i,0,t-1){//奇偶分组 
     79         if(i&1) a1[i>>1]=a[i];
     80         else a0[i>>1]=a[i];
     81     }
     82     complex*y0=FFT(a0,t>>1,opt),*y1=FFT(a1,t>>1,opt);//递归
     83     rep(i,0,(t>>1)-1){//利用t>>1的情况计算n的情况,注意公式的推导:A(x)=A0(x^2)+xA1(x^2) 
     84         y[i]=y0[i]+w*y1[i];
     85         y[i+(t>>1)]=y0[i]-w*y1[i];
     86         w=w*w1;
     87     }
     88     S[cnt++]=a0;S[cnt++]=a1;if(y0!=a0) S[cnt++]=y0;if(y1!=a1) S[cnt++]=y1;
     89     return y;
     90 }
     91 complex*DFT(complex a[],int t,int opt){//t为2的整数次幂 opt==1->FFT opt==-1->逆FFT
     92     t=rev(t);
     93     complex*ans=FFT(a,t,opt);
     94     if(opt==-1) rep(i,0,t-1){
     95         (ans+i)->r/=t;(ans+i)->i/=t;
     96     }
     97     return ans;
     98 }
     99 void init(){
    100     rep(i,0,maxk-1) S[cnt++]=pool[i];
    101 }
    102 int main(){
    103     //freopen("#intput.txt","r",stdin);
    104     //freopen("#output.txt","w",stdout);
    105     init();
    106     n=readint();m=readint();n++;m++;
    107     complex*a=newarray(),*b=newarray();
    108     rep(i,0,n-1) a[i].r=readint();
    109     rep(i,0,m-1) b[i].r=readint();
    110     int N=max(n,m);N=rev(N)<<1;
    111     complex*A=DFT(a,N,1),*B=DFT(b,N,1),*Ans;
    112     rep(i,0,N-1) A[i]=A[i]*B[i];
    113     Ans=DFT(A,N,-1);N--;
    114     rep(i,0,n+m-2){
    115         printf("%.0lf",(Ans+i)->r+esp);
    116         putchar(i==N?'
    ':' ');
    117     }
    118     //fclose(stdin);
    119     //fclose(stdout);
    120     return 0;
    121 }
    多项式乘法 手写栈 时空nlogn
      1 #include<cstdio> 
      2 #include<cstring>
      3 #include<cmath>
      4 #include<ctime>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<set>
      9 #define pi (3.14159265358979323846)
     10 #define maxint (2147483647)
     11 #define l(a) ((a)<<1)
     12 #define r(a) ((a)<<1|1)
     13 #define b(a) (1<<(a))
     14 #define esp (1e-4)
     15 #define rep(i,a,b) for(int i=a;i<=(b);i++)
     16 #define clr(a) memset(a,0,sizeof(a))
     17 typedef long long ll;
     18 using namespace std;
     19 int readint(){
     20     int t=0,f=1;char c=getchar();
     21     while(!isdigit(c)){
     22         if(c=='-') f=-1;
     23         c=getchar();
     24     }
     25     while(isdigit(c)){
     26         t=(t<<3)+(t<<1)+c-'0';
     27         c=getchar();
     28     }
     29     return t*f;
     30 }
     31 void readstr(char s[]){
     32     int p=0;char c=getchar();
     33     while(!isdigit(c)) c=getchar();
     34     while(isdigit(c)){
     35         s[p++]=c;c=getchar();
     36     }
     37 }
     38 const int maxn=250000;
     39 struct complex{
     40     double r,i;
     41     inline complex(double R,double I){
     42         r=R;i=I;
     43     }
     44     inline complex(){
     45         r=i=0;
     46     }
     47     inline complex operator+(complex A)const{
     48         return complex(A.r+r,A.i+i);
     49     }
     50     inline complex operator-(complex A)const{
     51         return complex(r-A.r,i-A.i);
     52     }
     53     inline complex operator*(complex A)const{
     54         return complex(A.r*r-A.i*i,A.r*i+A.i*r);
     55     }
     56     inline void out(){
     57         if(abs(i)>esp) printf("%.2lf+%.2lfi
    ",r,i);
     58         else printf("%.2lf
    ",r+esp);
     59     }
     60 };
     61 int n,n1,n2,ans[maxn];
     62 complex A[maxn],B[maxn],_A[maxn],_B[maxn];
     63 char a[maxn],b[maxn];
     64 int init(int n){
     65     int tmp=1;while(tmp<n) tmp<<=1;
     66     return tmp;
     67 }
     68 int rev(int t,int l){
     69     int _t=0;
     70     for(int i=0;b(i)<l;i++){
     71         _t<<=1;if(t&b(i)) _t|=1;
     72     }
     73     return _t;
     74 }
     75 complex*FFT(complex X[],complex Y[],int t,int opt){
     76     rep(i,0,t-1) Y[rev(i,t)]=X[i];
     77     for(int s=2;s<=t;s<<=1){
     78         complex w1=complex(cos(2*pi/s),sin(2*pi*opt/s));
     79         for(int k=0;k<t;k+=s){
     80             complex w=complex(1,0);
     81             rep(i,k,k+(s>>1)-1){
     82                 complex t1=Y[i],t2=w*Y[i+(s>>1)];
     83                 Y[i]=t1+t2;Y[i+(s>>1)]=t1-t2;
     84                 w=w*w1;
     85             }
     86         }
     87     }
     88     if(opt==-1) rep(i,0,t-1) Y[i].r/=t,Y[i].i/=t;
     89     return Y; 
     90 }
     91 int main(){
     92     //freopen("#input.txt","r",stdin);
     93     //freopen("#output.txt","w",stdout);
     94     n=readint();
     95     readstr(a);readstr(b);
     96     while(a[n1]=='0') n1++;while(b[n2]=='0') n2++;
     97     rep(i,n1,n-1) A[i-n1].r=a[i]-'0';rep(i,n2,n-1) B[i-n2].r=b[i]-'0';
     98     n1=n-n1;n2=n-n2;
     99     int N=init(n);
    100     FFT(A,_A,2*N,1);FFT(B,_B,2*N,1);
    101     rep(i,0,2*N) _A[i]=_A[i]*_B[i];
    102     FFT(_A,A,2*N,-1);
    103     rep(i,0,2*N) ans[i+1]=floor(A[i].r+esp);
    104     for(int i=2*N;i>=0;i--) if(ans[i]>9){
    105         ans[i-1]+=ans[i]/10;ans[i]%=10;
    106     }
    107     int cnt=0;while(!ans[cnt]) cnt++;
    108     rep(i,cnt,n1+n2-1) printf("%d",ans[i]);
    109     //fclose(stdin);
    110     //fclose(stdout);
    111     return 0;
    112 }
    大数乘法 注意精度!
     1 #include<cstdio> 
     2 #include<cstring>
     3 #include<cmath>
     4 #include<ctime>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<stack>
     9 #include<set>
    10 #define esp (1e-8)
    11 #define maxint (2147483647)
    12 #define pi (3.141592653589793)
    13 #define l(a) ((a)<<1)
    14 #define r(a) ((a)<<1|1)
    15 #define b(a) (1<<(a))
    16 #define rep(i,a,b) for(int i=a;i<=(b);i++)
    17 #define clr(a) memset(a,0,sizeof(a))
    18 typedef long long ll;
    19 using namespace std;
    20 int readint(){//只读入正整数 
    21     int t=0;char c=getchar();
    22     while(!isdigit(c)) c=getchar();
    23     while(isdigit(c)){
    24         t=(t<<3)+(t<<1)+c-'0';
    25         c=getchar();
    26     }
    27     return t;
    28 }
    29 const int maxn=3000009;//注意maxn的取值 
    30 int n,m;
    31 struct complex{
    32     double r,i;
    33     inline complex(double R,double I){
    34         r=R;i=I;
    35     }
    36     inline complex(){}
    37     inline void out(){
    38         if(abs(i)>esp) printf("%.2lf %.2lfi
    ",r,i);
    39         else printf("%.2lf
    ",r+esp);
    40     }
    41     inline complex operator +(const complex A)const{
    42         return complex(r+A.r,i+A.i);
    43     }
    44     inline complex operator -(const complex A)const{
    45         return complex(r-A.r,i-A.i);
    46     }
    47     inline complex operator *(const complex A)const{
    48         return complex(r*A.r-i*A.i,i*A.r+r*A.i);
    49     }
    50 };
    51 int rev(int t,int len){
    52     int ret=0;
    53     for(int i=0;b(i)<len;i++){//求逆序->利用性质 
    54         ret<<=1;if(t&b(i)) ret|=1;
    55     }
    56     return ret;
    57 }
    58 complex x1[maxn],x2[maxn],A[maxn],B[maxn];
    59 void DFT(complex Ans[],complex a[],int t,int opt){
    60     rep(i,0,t-1) Ans[rev(i,t)]=a[i];
    61     for(int s=1;b(s)<=t;s++){//当前迭代计算的子列长度为b(s) 
    62         int m=b(s);
    63         complex w1=complex(cos(2*pi/m),sin(2*pi/m*opt));
    64         for(int k=0;k<t;k+=m){//与递归一样的计算过程 
    65             complex w=complex(1,0);
    66             rep(j,0,(m>>1)-1){
    67                 complex t1=Ans[k+j],t2=w*Ans[k+j+(m>>1)];
    68                 Ans[k+j]=t1+t2;Ans[k+j+(m>>1)]=t1-t2;
    69                 w=w*w1;
    70             }
    71         }
    72     }
    73     if(opt==-1) rep(i,0,t-1) Ans[i].r/=t,Ans[i].i/=t;
    74 }
    75 int main(){
    76     //freopen("#intput.txt","r",stdin);
    77     //freopen("#output.txt","w",stdout);
    78     n=readint();m=readint();n++;m++;
    79     rep(i,0,n-1) x1[i].r=readint();
    80     rep(i,0,m-1) x2[i].r=readint();
    81     int t=0,N=max(n,m);
    82     while(b(t)<N) t++;N=b(t+1);
    83     DFT(A,x1,N,1);DFT(B,x2,N,1);
    84     rep(i,0,N-1) A[i]=A[i]*B[i];
    85     DFT(B,A,N,-1);
    86     rep(i,0,m+n-2){
    87         printf("%.0lf",B[i].r+esp);
    88         putchar(i==m+n-2?'
    ':' ');
    89     }
    90     //fclose(stdin);
    91     //fclose(stdout);
    92     return 0;
    93 }
    多项式乘法 迭代 n空间 nlogn时间 常数小

     uoj与洛谷都有题

    注意几个点:

    1、求rev

    2、w从(1,0)开始

    3、将n化为2^k

    cnblogs.com/rvalue/p/7351400.html

  • 相关阅读:
    selenium+python自动化86-Chrome正在受到自动软件的控制
    python笔记6-%u60A0和u60a0类似unicode解码
    百度网页搜索部
    百度:替换和清除空格
    百度:在O(1)空间复杂度范围内对一个数组中前后连段有序数组进行归并排序
    WLLCM这五个字母全排列数目
    r个有标志的球放进n个不同的盒子里,要求无一空盒,问有多少种不同的分配方案?
    从某一日期开始过day天的日期
    求从1到500的整数中能被3和5整除但不能被7整除的数的个数
    红、黄、蓝三色的球各8个,从中取出9个,要求每种颜色的球至少一个,问有多少种不同的取法?
  • 原文地址:https://www.cnblogs.com/chensiang/p/7793046.html
Copyright © 2011-2022 走看看