• Fast Fourier Transform


    写在前面的..

    感觉自己是应该学点新东西了.. 所以就挖个大坑,去学FFT了..

     


    FFT是个啥?

    坑已补上..

    推荐去看黑书《算法导论》,讲的很详细

     


    例题选讲


    1.UOJ #34. 多项式乘法

    这是FFT最裸的题目了 FFT就是拿来求这个东西的

    没啥好讲的,把板子贴一下吧..

     

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int Maxn = 400010;
     8 struct cp {
     9     double r, i;
    10     cp ( double r=0, double i=0 ) : r(r), i(i) {}
    11 }A[Maxn], B[Maxn]; int an, bn, n;
    12 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    13 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    14 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    15 double pi = acos(-1);
    16 void fft ( cp *a, int op ){
    17     int i, j, k;
    18     j = 0;
    19     for ( i = 0; i < n; i ++ ){
    20         if ( i < j ) swap ( a[i], a[j] );
    21         k = n>>1;
    22         while ( j & k ){ j -= k; k >>= 1; }
    23         j += k;
    24     }
    25     for ( i = 2; i <= n; i <<= 1 ){
    26         cp wn = cp ( cos (2.0*pi/i), op * sin (2.0*pi/i) );
    27         for ( j = 0; j < n; j += i ){
    28             cp w = cp ( 1, 0 );
    29             for ( k = j; k < j+i/2; k ++ ){
    30                 cp x = a[k], y = w*a[k+i/2];
    31                 a[k] = x+y; a[k+i/2] = x-y;
    32                 w = w*wn;
    33             }
    34         }
    35     }
    36     if ( op == -1 ) for ( i = 0; i < n; i ++ ) a[i].r /= n;
    37 }
    38 int main (){
    39     int i, j, k;
    40     scanf ( "%d%d", &an, &bn );
    41     n = 1; while ( n < an+bn+1 ) n <<= 1;
    42     for ( i = 0; i <= an; i ++ ) scanf ( "%lf", &A[i].r );
    43     for ( i = 0; i <= bn; i ++ ) scanf ( "%lf", &B[i].r );
    44     fft ( A, 1 ); fft ( B, 1 );
    45     for ( i = 0; i < n; i ++ ) A[i] = A[i]*B[i];
    46     fft ( A, -1 );
    47     for ( i = 0; i <= an+bn; i ++ ) printf ( "%d ", (int)(A[i].r+0.5) );
    48     printf ( "
    " );
    49     return 0;
    50 }
    View Code

     


    2.bzoj 3527: [Zjoi2014]力

    这题在bzoj上没有题面,百度一下就行了,给个链接吧

    化简一下公式:$$E_i=sumlimits_{j<i}dfrac{q_j}{(i-j)^2}-sumlimits_{j>i}dfrac{q_j}{(i-j)^2}$$

    然后你设$g_i=dfrac{1}{i^2}$,只考虑前面一部分的公式就可化成:$$E_i=sumlimits_{j<i}q_j imes g_{i-j}$$

    看是不是很眼熟,这就是很典型的FFT的模型

    然后后面的就把整个数组反过来搞就是同样的道理..

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int Maxn = 100010;
     8 struct cp {
     9     double r, i;
    10     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    11 }g[Maxn*4], h[Maxn*4];  int n, nn;
    12 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    13 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    14 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    15 double pi = acos (-1);
    16 void fft ( cp *a, int op ){
    17     int i, j, k;
    18     for ( i = j = 0; i < n; i ++ ){
    19         if ( i < j ) swap ( a[i], a[j] );
    20         k = n >> 1;
    21         while ( j & k ) j -= k, k >>= 1;
    22         j += k;
    23     }
    24     for ( i = 2; i <= n; i <<= 1 ){
    25         cp wn = cp ( cos (2.0*pi/i), op * sin (2.0*pi/i) );
    26         for ( j = 0; j < n; j += i ){
    27             cp w = cp ( 1, 0 );
    28             for ( k = j; k < j+i/2; k ++ ){
    29                 cp x = a[k], y = w*a[k+i/2];
    30                 a[k] = x+y; a[k+i/2] = x-y;
    31                 w = w*wn;
    32             }
    33         }
    34     }
    35     if ( op == -1 ) for ( i = 0; i < n; i ++ ) a[i].r /= n;
    36 }
    37 double q[Maxn], ans[Maxn];
    38 int main (){
    39     int i, j, k;
    40     scanf ( "%d", &nn );
    41     for ( i = 1; i <= nn; i ++ ) scanf ( "%lf", &q[i] );
    42     n = 1; while ( n < 2*nn+1 ) n <<= 1;
    43     for ( i = 1; i <= nn; i ++ ){
    44         g[i].r = q[i];
    45         h[i].r = (double)1/(double(i)*i);
    46     }
    47     fft ( g, 1 ); fft ( h, 1 );
    48     for ( i = 0; i < n; i ++ ) g[i] = g[i]*h[i];
    49     fft ( g, -1 );
    50     for ( i = 1; i <= nn; i ++ ) ans[i] += g[i].r;
    51  
    52     for ( i = 0; i <= n; i ++ ) g[i].r = g[i].i = h[i].r = h[i].i = 0;
    53     for ( i = 1; i <= nn; i ++ ){
    54         g[i].r = q[nn-i+1];
    55         h[i].r = (double)1/(double(i)*i);
    56     }
    57     fft ( g, 1 ); fft ( h, 1 );
    58     for ( i = 0; i < n; i ++ ) g[i] = g[i]*h[i];
    59     fft ( g, -1 );
    60     for ( i = 1; i <= nn; i ++ ) ans[i] -= g[nn-i+1].r;
    61     for ( i = 1; i <= nn; i ++ ) printf ( "%lf
    ", ans[i] );
    62     return 0;
    63 }
    View Code

    3.bzoj 3160: 万径人踪灭

    题意很长,但有用的不过那两句划线的..

    仔细想想,如果$s_i==s_j$,那么就可以对$dfrac{i+j}{2}$贡献答案了对吧

    再想想,如果我已经知道了这$2n-1$(包括了中间的插缝)位置有$x$对数贡献了答案,在不考虑连续一段、取空集的情况下是可以有$2^x$种答案的

    那么就在上面的基础上减去连续一段和空集的情况

    连续一段的可以用manacher判断出,空集直接减去$1$就好了

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int Maxn = 100010;
     8 const int Mod = 1e9+7;
     9 struct cp {
    10     double r, i;
    11     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    12 }A[Maxn*4];
    13 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    14 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    15 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    16 int n, nn;
    17 char s[Maxn*2]; int ans[Maxn*2];
    18 double pi = acos (-1);
    19 int _min ( int x, int y ){ return x < y ? x : y; }
    20 void fft ( cp *a, int op ){
    21     int i, j, k;
    22     for ( i = j = 0; i < n; i ++ ){
    23         if ( i < j ) swap ( a[i], a[j] );
    24         k = n >> 1;
    25         while ( j & k ) j -= k, k >>= 1;
    26         j += k;
    27     }
    28     for ( i = 2; i <= n; i <<= 1 ){
    29         cp wn = cp ( cos (2.0*pi/i), op*sin(2.0*pi/i) );
    30         for ( j = 0; j < n; j += i ){
    31             cp w = cp ( 1, 0 );
    32             for ( k = j; k < j+i/2; k ++ ){
    33                 cp x = a[k], y = w*a[k+i/2];
    34                 a[k] = x+y; a[k+i/2] = x-y;
    35                 w = w*wn;
    36             }
    37         }
    38     }
    39     if ( op == -1 ) for ( i = 0; i < n; i ++ ) a[i].r /= n;
    40 }
    41 int d[Maxn];
    42 int rad[Maxn*2];
    43 int main (){
    44     int i, j, k;
    45     scanf ( "%s", s );
    46     nn = strlen (s);
    47     d[0] = 1;
    48     for ( i = 1; i <= nn; i ++ ) d[i] = ( d[i-1] * 2 ) % Mod;
    49     n = 1; while ( n < 2*nn+1 ) n <<= 1;
    50     for ( i = 0; i < nn; i ++ ){
    51         if ( s[i] == 'a' ) A[i].r = 1;
    52     }
    53     fft ( A, 1 );
    54     for ( i = 0; i < n; i ++ ) A[i] = A[i]*A[i];
    55     fft ( A, -1 );
    56     for ( i = 0; i <= 2*(nn-1); i ++ ) ans[i] += ((int)(A[i].r+0.5)+1)/2;
    57  
    58     for ( i = 0; i < n; i ++ ) A[i].r = A[i].i = 0;
    59     for ( i = 0; i < nn; i ++ ){
    60         if ( s[i] == 'b' ) A[i].r = 1;
    61     }
    62     fft ( A, 1 );
    63     for ( i = 0; i < n; i ++ ) A[i] = A[i]*A[i];
    64     fft ( A, -1 );
    65     for ( i = 0; i <= 2*(nn-1); i ++ ) ans[i] += ((int)(A[i].r+0.5)+1)/2;
    66     int ret = 0;
    67     for ( i = nn-1; i >= 0; i -- ){
    68         s[i*2+2] = s[i];
    69         s[i*2+3] = '#';
    70     }
    71     s[0] = '$'; s[1] = '#'; s[2*nn+2] = '?';
    72     rad[0] = 0;
    73     k = 0; int mx = 0;
    74     for ( i = 1; i <= 2*nn; i ++ ){
    75         if ( mx > i ){ rad[i] = _min ( rad[2*k-i], mx-i ); }
    76         else rad[i] = 1;
    77         while ( s[i-rad[i]] == s[i+rad[i]] && i-rad[i] > 0 ) rad[i] ++;
    78         if ( i+rad[i]-1 > mx ){
    79             mx = i+rad[i]-1;
    80             k = i;
    81         }
    82     }
    83     for ( i = 0; i <= 2*(nn-1); i ++ ){
    84         ret = (ret+d[ans[i]]-rad[i+2]/2-1)%Mod;
    85     }
    86     printf ( "%d
    ", ret );
    87     return 0;
    88 }
    View Code

    4.bzoj 3509: [CodeChef] COUNTARI

    来自la1la1la的题解:

    1)先看一个比较sb的做法:枚举$j$,算出前面$i$的数的总数$sum[a[i]]$,然后找后面$k$,统计$sum[2*a[j]-a[k]]$

    时间复杂度为$O(n^2)$

    2)再看一个更sb的做法:枚举$j$,搞搞前面的和后面的,FFT计算,累加和为$2*a[j]$的方案

    时间复杂度为$O(n^2logn)$

    好,那么这题的正解就是把这两个sb做法合在一起

    用一种分块的方法,假设我们把每一块分成每块大小为$S$的

    枚举块内的$j$,用第一种方法暴力搞出块内的$i$、$k$的所有情况,时间复杂度为$O(nS)$

    对于块外的使用第二种方法,即FFT来做,再枚举块内$j$累计答案,时间复杂度为$O(frac{n}{S}mlogm)$,其中$m$是最大的数

    总时间是$O(nS+frac{n}{S}mlogm)$,这个时候锅就该甩给你们的高中老师了——均值不等式:$$a+bgeq 2sqrt{ab}$$

    那么这个时间就是大于等于$2nsqrt{mlogm}$,什么时候能取到等于呢,继续甩锅

    当$S=sqrt{mlogm}$就是了,你把$m=30000$带进去估算一下(记住要带点常数进去..)

    大概就是$S=1000$就差不多了 反正我就是这么打的..

     

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define LL long long
     7 using namespace std;
     8 const int Maxn = 100010;
     9 const int Maxm = 33000;
    10 struct cp {
    11     double r, i;
    12     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    13 }A[Maxm*4], B[Maxm*4]; int An;
    14 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    15 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    16 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    17 int a[Maxn], n, S;
    18 int _min ( int x, int y ){ return x < y ? x : y; }
    19 int _max ( int x, int y ){ return x > y ? x : y; }
    20 int ss[Maxm*2], ls[Maxm*2], rs[Maxm*2];
    21 double pi = acos(-1);
    22 void fft ( cp *a, int op ){
    23     int i, j, k;
    24     for ( i = j = 0; i < An; i ++ ){
    25         if ( i < j ) swap ( a[i], a[j] );
    26         k = An >> 1;
    27         while ( j & k ) j -= k, k >>= 1;
    28         j += k;
    29     }
    30     for ( i = 2; i <= An; i <<= 1 ){
    31         cp wn = cp ( cos (2.0*pi/i), op * sin (2.0*pi/i) );
    32         for ( j = 0; j < An; j += i ){
    33             cp w = cp ( 1, 0 );
    34             for ( k = j; k < j+i/2; k ++ ){
    35                 cp x = a[k], y = w*a[k+i/2];
    36                 a[k] = x+y; a[k+i/2] = x-y;
    37                 w = w*wn;
    38             }
    39         }
    40     }
    41     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i].r /= An;
    42 }
    43 int main (){
    44     int i, j, k;
    45     scanf ( "%d", &n );
    46     S = 1000;
    47     int mx = 0;
    48     for ( i = 1; i <= n; i ++ ){
    49         scanf ( "%d", &a[i] );
    50         rs[a[i]] ++;
    51         mx = _max ( mx, a[i] );
    52     }
    53     An = 1; while ( An < 2*mx+1 ) An <<= 1;
    54     LL ans = 0;
    55     for ( i = 1; i <= n; i += S ){
    56         int p = _min ( i+S-1, n );
    57         for ( j = i; j <= p; j ++ ) rs[a[j]] --;
    58         for ( j = i; j <= p; j ++ ){
    59             for ( k = j+1; k <= p; k ++ ){
    60                 if ( 2*a[j]-a[k] > 0 ) ans += (LL)ss[2*a[j]-a[k]]+ls[2*a[j]-a[k]];
    61             }
    62             ss[a[j]] ++;
    63             for ( k = i; k <= j-1; k ++ ){
    64                 if ( 2*a[j]-a[k] > 0 ) ans += (LL)rs[2*a[j]-a[k]];
    65             }
    66         }
    67         for ( j = 0; j < An; j ++ ){
    68             A[j].r = ls[j]; A[j].i = 0;
    69             B[j].r = rs[j]; B[j].i = 0;
    70         }
    71         fft ( A, 1 ); fft ( B, 1 );
    72         for ( j = 0; j < An; j ++ ) A[j] = A[j]*B[j];
    73         fft ( A, -1 );
    74         for ( j = i; j <= p; j ++ ){
    75             ans += (LL)(A[2*a[j]].r+0.5);
    76         }
    77         for ( j = i; j <= p; j ++ ) ss[a[j]] --, ls[a[j]] ++;
    78     }
    79     printf ( "%lld
    ", ans );
    80     return 0;
    81 }
    82 
    View Code

     


    5.hdu 5730 Shell Necklace

    先把原题公式化简一下就是:$$dp_i=sumlimits_{j=1}^{i-1}a_{i-j} imes dp_j$$

    那么的话就是cdq分治搞一下再套一个FFT计算更新答案了..

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int Maxn = 100010;
     8 const int Mod = 313;
     9 struct cp {
    10     double r, i;
    11     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    12 }A[Maxn*4], B[Maxn*4]; int An;
    13 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    14 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    15 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    16 int a[Maxn], n, f[Maxn];
    17 double pi = acos (-1);
    18 void fft ( cp *a, int op ){
    19     int i, j, k;
    20     for ( i = j = 0; i < An; i ++ ){
    21         if ( i < j ) swap ( a[i], a[j] );
    22         k = An >> 1;
    23         while ( j & k ) j -= k, k >>= 1;
    24         j += k;
    25     }
    26     for ( i = 2; i <= An; i <<= 1 ){
    27         cp wn = cp ( cos (2*pi/i), op * sin (2*pi/i) );
    28         for ( j = 0; j < An; j += i ){
    29             cp w = cp ( 1, 0 );
    30             for ( k = j; k < j+i/2; k ++ ){
    31                 cp x = a[k], y = w*a[k+i/2];
    32                 a[k] = x+y; a[k+i/2] = x-y;
    33                 w = w*wn;
    34             }
    35         }
    36     }
    37     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i].r /= An;
    38 }
    39 void cdq ( int l, int r ){
    40     if ( l == r ) return;
    41     int mid = ( l + r ) >> 1;
    42     cdq ( l, mid );
    43     int i, j, k;
    44     int len = r-l;
    45     An = 1; while ( An < 2*len+1 ) An <<= 1;
    46     for ( i = l; i <= mid; i ++ ){
    47         A[i-l].r = f[i]; A[i-l].i = 0;
    48         B[i-l].r = a[i-l]; B[i-l].i = 0;
    49     }
    50     for ( i = mid+1; i <= r; i ++ ){
    51         A[i-l].r = 0; A[i-l].i = 0;
    52         B[i-l].r = a[i-l]; B[i-l].i = 0;
    53     }
    54     for ( i = len+1; i < An; i ++ ) A[i].r = A[i].i = B[i].r = B[i].i = 0;
    55     fft ( A, 1 ); fft ( B, 1 );
    56     for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    57     fft ( A, -1 );
    58     for ( i = mid+1; i <= r; i ++ ){
    59         int ret = (int)(A[i-l].r+0.5);
    60         ret %= Mod;
    61         f[i] = ( f[i] + ret ) % Mod;
    62     }
    63     cdq ( mid+1, r );
    64 }
    65 int main (){
    66     int i, j, k;
    67     while ( scanf ( "%d", &n ) != EOF ){
    68         if ( n == 0 ) break;
    69         for ( i = 1; i <= n; i ++ ){
    70             scanf ( "%d", &a[i] ); a[i] %= Mod;
    71             f[i] = 0;
    72         }
    73         f[0] = 1;
    74         cdq ( 0, n );
    75         printf ( "%d
    ", f[n] );
    76     }
    77     return 0;
    78 }
    View Code

    6.hdu 5307 He is Flying

    题意:有$n$段路,每段路长度为$s_i$,你从节点$i$到节点$j$,可以获得一个开心值$j−i+1$,然后问你,主人公走过了所有总长度为$s$的段,问你有多少开心值。

    %%%la1la1la

    累计一个前缀和$sum$,那么题意就变成走$sum_j-sum_i$的路程获得$j-i$的开心值

    那么就把$j$和$-i$分开来算,卷积一下就好了..

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define LL long long
     7 #define LD long double
     8 using namespace std;
     9 const LL Maxn = 100010;
    10 const LL Maxs = 50010;
    11 struct cp {
    12     LD r, i;
    13     cp ( LD r=0.0, LD i=0.0 ) : r(r), i(i) {}
    14 }A[Maxs*4], B[Maxs*4]; LL An;
    15 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    16 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    17 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    18 LL sum[Maxn], n, ans[Maxs];
    19 const LD pi = acos (-1);
    20 void fft ( cp *a, LL op ){
    21     LL i, j, k;
    22     for ( i = j = 0; i < An; i ++ ){
    23         if ( i < j ) swap ( a[i], a[j] );
    24         k = An >> 1;
    25         while ( j & k ) j -= k, k >>= 1;
    26         j += k;
    27     }
    28     for ( i = 2; i <= An; i <<= 1 ){
    29         for ( j = 0; j < An; j += i ){
    30             for ( k = j; k < j+i/2; k ++ ){
    31                 cp x = a[k], y = cp ( cos (2*pi*(k-j)/i), op * sin (2*pi*(k-j)/i) ) * a[k+i/2];
    32                 a[k] = x+y; a[k+i/2] = x-y;
    33             }
    34         }
    35     }
    36     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i].r /= An;
    37 }
    38 LL ss[Maxn];
    39 int main (){
    40     LL i, j, k, T;
    41     for ( i = 1; i <= 100000; i ++ ) ss[i] = ss[i-1]+i*(i+1)/2;
    42     scanf ( "%I64d", &T );
    43     while ( T -- ){
    44         scanf ( "%I64d", &n );
    45         LL lj = 0, ret = 0;
    46         for ( i = 1; i <= n; i ++ ){
    47             scanf ( "%I64d", &sum[i] );
    48             if ( sum[i] == 0 ) lj ++;
    49             else {
    50                 ret += ss[lj];
    51                 lj = 0;
    52             }
    53             sum[i] += sum[i-1];
    54         }
    55         ret += ss[lj];
    56         printf ( "%I64d
    ", ret );
    57         for ( i = 0; i <= sum[n]; i ++ ) ans[i] = 0;
    58         An = 1; while ( An < sum[n]*2 ) An <<= 1;
    59         for ( i = 0; i < An; i ++ ) A[i].r = A[i].i = B[i].r = B[i].i = 0;
    60         for ( i = 0; i <= n; i ++ ){
    61             A[sum[n]-sum[i]].r += i;
    62             B[sum[i]].r += 1;
    63         }
    64         fft ( A, 1 ); fft ( B, 1 );
    65         for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    66         fft ( A, -1 );
    67         for ( i = 0; i <= sum[n]; i ++ ) ans[i] = -(LL)(A[sum[n]+i].r+0.5);
    68         for ( i = 0; i < An; i ++ ) A[i].r = A[i].i = B[i].r = B[i].i = 0;
    69         for ( i = 0; i <= n; i ++ ){
    70             A[sum[n]-sum[i]].r += 1;
    71             B[sum[i]].r += i;
    72         }
    73         fft ( A, 1 ); fft ( B, 1 );
    74         for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    75         fft ( A, -1 );
    76         for ( i = 0; i <= sum[n]; i ++ ) ans[i] += (LL)(A[sum[n]+i].r+0.5);
    77         for ( i = 1; i <= sum[n]; i ++ ) printf ( "%I64d
    ", ans[i] );
    78     }
    79     return 0;
    80 }
    View Code

    7.hdu 4609/bzoj 3513 3-idiots

    题意:给你$n$条边,问你任取三条边能组成三角形的概率

    按权值卷积后,把边排序

    对于任意一条边你都能知道其余两条边加起来大于它的方案数

    考虑第$i$条边是最长边,那么就要减去一条选大的一条选小的、两条都选大的方案数,这些都可以用组合公式算得..

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define LL long long
     7 using namespace std;
     8 const LL Maxn = 100010;
     9 struct cp {
    10     double r, i;
    11     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    12 }A[Maxn*4]; LL An;
    13 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    14 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    15 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    16 LL a[Maxn], n;
    17 LL ans[Maxn*2];
    18 const double pi = acos (-1);
    19 LL _max ( LL x, LL y ){ return x > y ? x : y; }
    20 void fft ( cp *a, LL op ){
    21     LL i, j, k;
    22     for ( i = j = 0; i < An; i ++ ){
    23         if ( i < j ) swap ( a[i], a[j] );
    24         k = An >> 1;
    25         while ( j & k ) j -= k, k >>= 1;
    26         j += k;
    27     }
    28     for ( i = 2; i <= An; i <<= 1 ){
    29         cp wn = cp ( cos (2*pi/i), op * sin (2*pi/i) );
    30         for ( j = 0; j < An; j += i ){
    31             cp w = cp ( 1, 0 );
    32             for ( k = j; k < j+i/2; k ++ ){
    33                 cp x = a[k], y = w*a[k+i/2];
    34                 a[k] = x+y; a[k+i/2] = x-y;
    35                 w = w*wn;
    36             }
    37         }
    38     }
    39     if ( op == -1 ) for ( i = 0; i < An; i ++ ) A[i].r /= An;
    40 }
    41 int main (){
    42     LL i, j, k, T;
    43     scanf ( "%I64d", &T );
    44     while ( T -- ){
    45         scanf ( "%I64d", &n );
    46         LL mx = 0;
    47         for ( i = 1; i <= n; i ++ ){
    48             scanf ( "%I64d", &a[i] );
    49             mx = _max ( mx, a[i] );
    50         }
    51         An = 1;    while ( An < 2*mx+1 ) An <<= 1;
    52         for ( i = 0; i < An; i ++ ) A[i].r = A[i].i = 0;
    53         for ( i = 1; i <= n; i ++ ){
    54             A[a[i]].r += 1;
    55         }
    56         fft ( A, 1 );
    57         for ( i = 0; i < An; i ++ ) A[i] = A[i]*A[i];
    58         fft ( A, -1 );
    59         for ( i = 1; i <= mx*2; i ++ ) ans[i] = (LL)(A[i].r+0.5);
    60         for ( i = 1; i <= n; i ++ ) ans[2*a[i]] --;
    61         for ( i = 1; i <= mx*2; i ++ ) ans[i] /= 2;
    62         for ( i = mx*2-1; i >= 1; i -- ) ans[i] += ans[i+1];
    63         sort ( a+1, a+n+1 );
    64         LL ret = 0;
    65         for ( i = 1; i <= n; i ++ ){
    66             ret += (LL)ans[a[i]+1]-n+1;
    67             ret -= (LL)(n-i)*(i-1);
    68             ret -= (LL)(n-i)*(n-i-1)/2;
    69         }
    70         LL zs = n*(n-1)*(n-2)/6;
    71         printf ( "%.7lf
    ", (double)ret/zs );
    72     }
    73     return 0;
    74 }
    View Code

    8.hdu 5751 Eades

    题意:

     

    Peter有一个序列$a_1, a_2, ..., a_n$. 定义$g(l,r)$表示子序列$a_{l},a_{l+1},...,a_{r}$的最大值, $f(l,r)=displaystylesum_{i=l}^{r}[a_i = g(l,r)]$. 注意$[ ext{condition}] = 1$当且仅当$ ext{condition}$是true, 否则$[ ext{condition}] = 0$.

     

    对于每个整数$k in {1, 2, ..., n}$, Peter想要知道有多少整数对$l$和$r$ $(l le r)$满足$f(l,r)=k$.

     

    官方题解:

     

    枚举每个数$x$, 考虑这个数成为最大值的对每个$z(cdot)$的贡献. 对于每个数$x$, 你都可以求出若干个极大区间$[l_x,r_x]$, 表示这个$x$在区间内是最大值, 不妨假设这个$x$在$[l_x,r_x]$出现了$m$次, 每个位置分别为$p_1,p_2,...,p_m$, 那么就可以转化成一个长度为$m+1$的序列$c_0,c_2,...,c_m$. 其中$c_0=p_1-l+1$ $c_{m}=r-p_m+1$ $c_i=p_{i+1}-p_{i}, 1 leq i < m$

     

    于是对$z_k$的贡献就是$z_k=sum_{i=0}^{m}c_i cdot c_{i+k}$

     

    这个其实就是$c_0,c_1,...,c_m$和$c_m,c_{m-1},...,c_0$的卷积, 做一次fft就好了.

    时间复杂度分析:因为每一个数只有可能进入一次做fft,所以总时间均摊$O(nlogn)$

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #define LL long long
     8 using namespace std;
     9 const LL Maxn = 100010;
    10 struct cp {
    11     double r, i;
    12     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    13 }A[Maxn*4], B[Maxn*4]; LL An;
    14 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    15 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    16 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    17 LL a[Maxn], maxx[Maxn*4], n;
    18 vector <LL> vec[Maxn];
    19 LL _max ( LL x, LL y ){ return x > y ? x : y; }
    20 void bulid_tree ( LL now, LL L, LL R ){
    21     if ( L < R ){
    22         LL mid = ( L + R ) >> 1, lc = now*2, rc = now*2+1;
    23         bulid_tree ( lc, L, mid );
    24         bulid_tree ( rc, mid+1, R );
    25         maxx[now] = _max ( maxx[lc], maxx[rc] );
    26     }
    27     else maxx[now] = a[L];
    28 }
    29 LL query ( LL now, LL L, LL R, LL l, LL r ){
    30     if ( L == l && R == r ) return maxx[now];
    31     LL mid = ( L + R ) >> 1, lc = now*2, rc = now*2+1;
    32     if ( r <= mid ) return query ( lc, L, mid, l, r );
    33     else if ( l > mid ) return query ( rc, mid+1, R, l, r );
    34     else return _max ( query ( lc, L, mid, l, mid ), query ( rc, mid+1, R, mid+1, r ) );
    35 }
    36 LL ans[Maxn];
    37 const double pi = acos (-1);
    38 void fft ( cp *a, LL op ){
    39     LL i, j, k;
    40     for ( i = j = 0; i < An; i ++ ){
    41         if ( i < j ) swap ( a[i], a[j] );
    42         k = An >> 1;
    43         while ( j & k ) j -= k, k >>= 1;
    44         j += k;
    45     }
    46     for ( i = 2; i <= An; i <<= 1 ){
    47         cp wn = cp ( cos (2*pi/i), op * sin (2*pi/i) );
    48         for ( j = 0; j < An; j += i ){
    49             cp w = cp ( 1, 0 );
    50             for ( k = j; k < j+i/2; k ++ ){
    51                 cp x = a[k], y = w*a[k+i/2];
    52                 a[k] = x+y; a[k+i/2] = x-y;
    53                 w = w*wn;
    54             }
    55         }
    56     }
    57     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i].r /= An;
    58 }
    59 void solve ( LL l, LL r ){
    60     if ( l > r ) return;
    61     LL i, j, k;
    62     LL Max = query ( 1, 1, n, l, r );
    63     LL x = lower_bound ( vec[Max].begin (), vec[Max].end (), l ) - vec[Max].begin ();
    64     LL y = upper_bound ( vec[Max].begin (), vec[Max].end (), r ) - vec[Max].begin ();
    65     An = 1; while ( An < 2*(y-x)+1 ) An <<= 1;
    66     for ( i = 0; i < An; i ++ ) A[i].r = A[i].i = B[i].r = B[i].i = 0;
    67     A[0].r = vec[Max][x]-l+1;
    68     for ( i = x; i < y-1; i ++ ){
    69         A[i-x+1].r = vec[Max][i+1]-vec[Max][i];
    70     }
    71     A[y-x].r = r-vec[Max][y-1]+1;
    72     for ( i = 0; i <= y-x; i ++ ) B[i].r = A[y-x-i].r;
    73     fft ( A, 1 ); fft ( B, 1 );
    74     for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    75     fft ( A, -1 );
    76     for ( i = 1; i <= y-x; i ++ ) ans[i] += (LL)(A[i+y-x].r+0.5);
    77     solve ( l, vec[Max][x]-1 );
    78     for ( i = x; i < y-1; i ++ ) solve ( vec[Max][i]+1, vec[Max][i+1]-1 );
    79     solve ( vec[Max][y-1]+1, r );
    80 }
    81 int main (){
    82     LL i, j, k, T;
    83     scanf ( "%I64d", &T );
    84     while ( T -- ){
    85         scanf ( "%I64d", &n );
    86         for ( i = 1; i <= n; i ++ ) vec[i].clear ();
    87         for ( i = 1; i <= n; i ++ ){ scanf ( "%I64d", &a[i] ); vec[a[i]].push_back (i); }
    88         bulid_tree ( 1, 1, n );
    89         for ( i = 1; i <= n; i ++ ) ans[i] = 0;
    90         solve ( 1, n );
    91         LL ret = 0;
    92         for ( i = 1; i <= n; i ++ ){
    93             ret += ans[i]^i;
    94         }
    95         printf ( "%I64d
    ", ret );
    96     }
    97     return 0;
    98 }
    View Code

     9.bzoj 4332: JSOI2012 分零食

    简化题意:把$m$分到$n$个位置,允许后缀为$0$,每个位置的值为$f(i)=Oi^2+Si+U$,其中$i$是该位置分到的数,问你所有情况的权值积的和

    找到三种做法:

    YJQ大爷

    WerKeyTom (讲道理不是很理解..)

    某大神 (比较厉害的做法..)

    我就是用YJQ大爷的方法的.. 他的题解讲的不是很详细就来补充一下吧

    设$f_{i,j}$表示把$j$分到$i$个位置而且全部填满没有后缀$0$的答案

    $g_{i,j}$表示把$j$分到$i$个位置而且一定至少有一个空没填的答案

    由于$nleq 10^8$,所以肯定是要用倍增的方法

    然后就是可以这么推:$$f_{i,j}=sumlimits_{k=1}^{j-1}f_{frac{i}{2},j-k}cdot f_{frac{i}{2},k}$$

    $$g_{i,j}=sumlimits_{k=1}^{j-1}g_{frac{i}{2},j-k}cdot f_{frac{i}{2},k}$$

    大概就是这样..

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int Maxn = 10010;
     8 int m, P, n, O, S, U;
     9 struct cp {
    10     double r, i;
    11     cp ( double r=0.0, double i=0.0 ) : r(r), i(i) {}
    12 }A[Maxn*4], B[Maxn*4];
    13 cp operator + ( cp a, cp b ){ return cp ( a.r+b.r, a.i+b.i ); }
    14 cp operator - ( cp a, cp b ){ return cp ( a.r-b.r, a.i-b.i ); }
    15 cp operator * ( cp a, cp b ){ return cp ( a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r ); }
    16 int f[Maxn*4], g[Maxn*4], ansf[Maxn*4], ansg[Maxn*4], An;
    17 int rev[Maxn*4];
    18 const double pi = acos (-1);
    19 void fft ( cp *a, int op ){
    20     int i, j, k;
    21     for ( i = 0; i < An; i ++ ) if ( i < rev[i] ) swap ( a[i], a[rev[i]] );
    22     for ( i = 2; i <= An; i <<= 1 ){
    23         cp wn = cp ( cos (2*pi/i), op * sin (2*pi/i) );
    24         for ( j = 0; j < An; j += i ){
    25             cp w = cp ( 1, 0 );
    26             for ( k = j; k < j+i/2; k ++ ){
    27                 cp x = a[k], y = w*a[k+i/2];
    28                 a[k] = x+y; a[k+i/2] = x-y;
    29                 w = w*wn;
    30             }
    31         }
    32     }
    33     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i].r /= An;
    34 }
    35 int main (){
    36     int i, j, k;
    37     scanf ( "%d%d%d%d%d%d", &m, &P, &n, &O, &S, &U );
    38     An = 1; while ( An < 2*m+1 ) An <<= 1;
    39     j = 0;
    40     for ( i = 0; i < An; i ++ ){
    41         rev[i] = j;
    42         k = An >> 1;
    43         while ( j & k ) j -= k, k >>= 1;
    44         j += k;
    45     }
    46     g[0] = 1;
    47     for ( i = 1; i <= m; i ++ ){
    48         f[i] = (((O*i)%P*i)%P+(S*i)%P+U)%P;
    49     }
    50     ansf[0] = 1; ansg[0] = 0;
    51     while (n){
    52         if ( n & 1 ){
    53             for ( i = 0; i <= m; i ++ ) A[i].r = ansf[i], B[i].r = g[i], A[i].i = B[i].i = 0;
    54             for ( i = m+1; i < An; i ++ ) A[i].r = B[i].r = A[i].i = B[i].i = 0;
    55             fft ( A, 1 ); fft ( B, 1 );
    56             for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    57             fft ( A, -1 );
    58             for ( i = 0; i <= m; i ++ ) ansg[i] = ( ansg[i] + ((int)(A[i].r+0.5))%P ) % P;
    59             
    60             for ( i = 0; i <= m; i ++ ) A[i].r = ansf[i], B[i].r = f[i], A[i].i = B[i].i = 0;
    61             for ( i = m+1; i < An; i ++ ) A[i].r = B[i].r = A[i].i = B[i].i = 0;
    62             fft ( A, 1 ); fft ( B, 1 );
    63             for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    64             fft ( A, -1 );
    65             for ( i = 0; i <= m; i ++ ) ansf[i] = ((int)(A[i].r+0.5))%P;
    66         }
    67         for ( i = 0; i <= m; i ++ ) A[i].r = f[i], B[i].r = g[i], A[i].i = B[i].i = 0;
    68         for ( i = m+1; i < An; i ++ ) A[i].r = B[i].r = A[i].i = B[i].i = 0;
    69         fft ( A, 1 ); fft ( B, 1 );
    70         for ( i = 0; i < An; i ++ ) A[i] = A[i]*B[i];
    71         fft ( A, -1 );
    72         for ( i = 0; i <= m; i ++ ) g[i] = ( g[i] + ((int)(A[i].r+0.5))%P ) % P;
    73         
    74         for ( i = 0; i <= m; i ++ ) A[i].r = f[i], A[i].i = 0;
    75         for ( i = m+1; i < An; i ++ ) A[i].r = A[i].i = 0;
    76         fft ( A, 1 );
    77         for ( i = 0; i < An; i ++ ) A[i] = A[i]*A[i];
    78         fft ( A, -1 );
    79         for ( i = 0; i <= m; i ++ ) f[i] = ((int)(A[i].r+0.5))%P;
    80         n >>= 1;
    81     }
    82     printf ( "%d
    ", (ansf[m]+ansg[m])%P );
    83     return 0;
    84 }
    View Code

     10.bzoj 3456: 城市规划

    这是一道比较厉害的NTT题目.. 我不是很会解释,建议去看看WerKeyTom的blog

    这道题的时间也比较坑,我卡了很久的常数才过..

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <ctime>
     6 #include <iostream>
     7 #define LL long long
     8 using namespace std;
     9 const LL Maxn = 130010;
    10 const LL Mod = 1004535809;
    11 const LL G = 3;
    12 LL A[Maxn*4], B[Maxn*4], An;
    13 LL pow ( LL x, LL k ){
    14     LL ret = 1;
    15     while (k){
    16         if ( k & 1 ) ret = (ret*x)%Mod;
    17         x = (x*x)%Mod;
    18         k >>= 1;
    19     }
    20     return ret;
    21 }
    22 LL v[Maxn], f[Maxn], jc[Maxn], fjc[Maxn], n, inv[Maxn], cf[Maxn*4], fcf[Maxn*4], p[Maxn];
    23 void dft ( LL *a, LL op ){
    24     LL i, j, k;
    25     for ( i = j = 0; i < An; i ++ ){
    26         if ( i < j ) swap ( a[i], a[j] );
    27         k = An >> 1;
    28         while ( j & k ) j -= k, k >>= 1;
    29         j += k;
    30     }
    31     for ( i = 2; i <= An; i <<= 1 ){
    32         LL wn = op > 0 ? cf[i] : fcf[i];
    33         LL w = 1;
    34         for ( k = 0; k < i/2; k ++ ){
    35             for ( j = 0; j < An; j += i ){
    36                 LL x = a[k+j], y = (w*a[k+j+i/2])%Mod;
    37                 a[k+j] = (x+y)%Mod; a[k+j+i/2] = (x-y+Mod)%Mod;
    38             }
    39             w = (w*wn)%Mod;
    40         }
    41     }
    42     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i] = (a[i]*inv[An])%Mod;
    43 }
    44 void cdq ( LL l, LL r ){
    45     if ( l == r ){ f[l] = (v[l]-(jc[l-1]*f[l])%Mod+Mod)%Mod; return; }
    46     LL mid = ( l + r ) >> 1, i;
    47     cdq ( l, mid );
    48     LL len = r-l+1;
    49     An = 1; while ( An < 2*len+1 ) An <<= 1;
    50     for ( i = 0; i < An; i ++ ) A[i] = B[i] = 0;
    51     for ( i = 0; i < len; i ++ ) B[i] = p[i];
    52     for ( i = 0; i < mid-l+1; i ++ ) A[i] = (f[i+l]*fjc[i+l-1])%Mod; 
    53     dft ( A, 1 ); dft ( B, 1 );
    54     for ( i = 0; i < An; i ++ ) A[i] = (A[i]*B[i])%Mod;
    55     dft ( A, -1 );
    56     for ( i = mid+1; i <= r; i ++ ) f[i] = (f[i]+A[i-l])%Mod;
    57     cdq ( mid+1, r );
    58 }
    59 int c[Maxn];
    60 int main (){
    61     LL i, j, k;
    62     scanf ( "%lld", &n );
    63     jc[0] = 1; fjc[0] = 1; v[0] = 1;
    64     c[0] = 1; for ( i = 1; i <= n; i ++ ) c[i] = (c[i-1]*2)%Mod;
    65     for ( i = 1; i <= n; i ++ ){
    66         v[i] = ( v[i-1] * c[i-1] ) % Mod;
    67         jc[i] = (jc[i-1]*i)%Mod;
    68     }
    69     fjc[n] = pow ( jc[n], Mod-2 );
    70     for ( i = n-1; i >= 1; i -- ){
    71         fjc[i] = (fjc[i+1]*(i+1))%Mod;
    72         p[i] = (v[i]*fjc[i])%Mod;
    73     }
    74     An = 1; while ( An < 2*n+1 ) An <<= 1;
    75     for ( i = 2; i <= An; i <<= 1 ) cf[i] = pow ( G, (Mod-1)/i ), fcf[i] = pow ( G, Mod-1-(Mod-1)/i ), inv[i] = pow ( i, Mod-2 );
    76     cdq ( 1, n );
    77     printf ( "%lld
    ", f[n] );
    78     return 0;
    79 }
    View Code

    11.bzoj 4555: [Tjoi2016&Heoi2016]求和

    把公式化一下基本就出来了,这里给出几个公式:

    斯特林数化简公式:$$S(n,m)=dfrac{1}{m!}sumlimits_{k=0}^{m}(-1)^kcdot C_m^kcdot (m-k)^n$$

    等比数列求和公式:$$Sum=dfrac{a(q^k-1)}{q-1}$$

    那么最后化成的公式为:$$f(n)=sumlimits_{j=0}^n2^jcdot j!sumlimits_{k=0}^jg(k)cdot h(j-k)$$

    $$g(i)=dfrac{(-1)^i}{i!}, h(i)=dfrac{sum_{k=0}^{n}i^k}{i!}$$

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #define LL long long
     6 using namespace std;
     7 const LL Maxn = 100010;
     8 const LL Mod = 998244353;
     9 const LL G = 3;
    10 LL jc[Maxn], inv[Maxn], invn;
    11 LL pow ( LL x, LL k ){
    12     LL ret = 1;
    13     while (k){
    14         if ( k & 1 ) ret = (ret*x)%Mod;
    15         x = (x*x)%Mod;
    16         k >>= 1;
    17     }
    18     return ret;
    19 }
    20 LL A[Maxn*4], B[Maxn*4], An;
    21 LL n;
    22 LL dft ( LL *a, LL op ){
    23     LL i, j, k;
    24     for ( i = j = 0; i < An; i ++ ){
    25         if ( i < j ) swap ( a[i], a[j] );
    26         k = An >> 1;
    27         while ( j & k ) j -= k, k >>= 1;
    28         j += k;
    29     }
    30     for ( i = 2; i <= An; i <<= 1 ){
    31         LL wn = pow ( G, op > 0 ? (Mod-1)/i : Mod-1-(Mod-1)/i );
    32         for ( j = 0; j < An; j += i ){
    33             LL w = 1;
    34             for ( k = j; k < j+i/2; k ++ ){
    35                 LL x = a[k], y = (w*a[k+i/2])%Mod;
    36                 a[k] = (x+y)%Mod; a[k+i/2] = (x-y+Mod)%Mod;
    37                 w = (w*wn)%Mod;
    38             }
    39         }
    40     }
    41     if ( op == -1 ) for ( i = 0; i < An; i ++ ) a[i] = (a[i]*invn)%Mod;
    42 }
    43 int main (){
    44     LL i, j, k;
    45     scanf ( "%lld", &n );
    46     An = 1; while ( An < 2*n+1 ) An <<= 1;
    47     jc[0] = jc[1] = 1;
    48     for ( i = 2; i <= n; i ++ ) jc[i] = (jc[i-1]*i)%Mod;
    49     inv[n] = pow ( jc[n], Mod-2 );
    50     for ( i = n-1; i >= 1; i -- ) inv[i] = (inv[i+1]*(i+1))%Mod;
    51     A[0] = 1;
    52     for ( i = 1; i <= n; i ++ ) A[i] = i % 2 == 1 ? Mod-inv[i] : inv[i];
    53     B[0] = 1; B[1] = n+1;
    54     for ( i = 2; i <= n; i ++ ) B[i] = ( ( ( pow ( i, n+1 ) - 1 ) * pow ( i-1, Mod-2 ) ) % Mod * inv[i] ) % Mod;
    55     invn = pow ( An, Mod-2 );
    56     dft ( A, 1 ); dft ( B, 1 );
    57     for ( i = 0; i < An; i ++ ) A[i] = (A[i]*B[i])%Mod;
    58     dft ( A, -1 );
    59     LL s = 1, ans = 0;
    60     for ( i = 0; i <= n; i ++ ){
    61         ans = ( ans + ((s*jc[i])%Mod*A[i])%Mod ) % Mod;
    62         s = (s*2)%Mod;
    63     }
    64     printf ( "%lld
    ", ans );
    65     return 0;
    66 }
    67 
    View Code

    参考资料

    picks的blog

  • 相关阅读:
    访问修饰符的权限。
    字符编码
    3/11 作业
    3/10 作业
    作业 3/9
    流程控制之for循环
    Exception in createBlockOutputStream
    windows上传文件到 linux的hdfs
    win10 配置 hadoop-2.7.2
    hadoop 源码编译
  • 原文地址:https://www.cnblogs.com/darklove/p/6002092.html
Copyright © 2020-2023  润新知