zoukankan      html  css  js  c++  java
  • bzoj2194 快速傅里叶之二

    题意:对于k = 0 ... n求

    解:

    首先把i变成从0开始

    我们发现a和b的次数(下标)是成正比例的,这不可,于是反转就行了。

    反转b的话,会发现次数和是n + k,这不可。

    反转a就很吼了。

    这个东西恰好是卷积出来的第n - k项的系数。

    所以我们把a串反转,然后用a与b卷积,最后再反转输出即可。

     1 /**************************************************************
     2     Problem: 2194
     3     Language: C++
     4     Result: Accepted
     5     Time:133643896 ms
     6     Memory:14342474884 kb
     7 ****************************************************************/
     8  
     9 #include <cstdio>
    10 #include <algorithm>
    11 #include <cmath>
    12 #include <cstring>
    13  
    14 const int N = 100010;
    15 const double pi = 3.1415926535897932384626;
    16  
    17 struct cp {
    18     double x, y;
    19     cp(double X = 0, double Y = 0) {
    20         x = X;
    21         y = Y;
    22     }
    23     inline cp operator +(const cp &w) const {
    24         return cp(x + w.x, y + w.y);
    25     }
    26     inline cp operator -(const cp &w) const {
    27         return cp(x - w.x, y - w.y);
    28     }
    29     inline cp operator *(const cp &w) const {
    30         return cp(x * w.x - y * w.y, x * w.y + y * w.x);
    31     }
    32 }a[N << 2], b[N << 2];
    33  
    34 int r[N << 2];
    35  
    36 inline void FFT(int n, cp *a, int f) {
    37     for(int i = 0; i < n; i++) {
    38         if(i < r[i]) {
    39             std::swap(a[i], a[r[i]]);
    40         }
    41     }
    42      
    43     for(int len = 1; len < n; len <<= 1) {
    44         cp Wn(cos(pi / len), f * sin(pi / len));
    45         for(int i = 0; i < n; i += (len << 1)) {
    46             cp w(1, 0);
    47             for(int j = 0; j < len; j++) {
    48                 cp t = a[i + len + j] * w;
    49                 a[i + len + j] = a[i + j] - t;
    50                 a[i + j] = a[i + j] + t;
    51                 w = w * Wn;
    52             }
    53         }
    54     }
    55      
    56     if(f == -1) {
    57         for(int i = 0; i <= n; i++) {
    58             a[i].x /= n;
    59         }
    60     }
    61     return;
    62 }
    63  
    64 int main() {
    65     int n;
    66     scanf("%d", &n);
    67     n--;
    68     for(int i = 0; i <= n; i++) {
    69         scanf("%lf%lf", &a[n - i].x, &b[i].x);
    70     }
    71      
    72     int len = 2, lm = 1;
    73     while(len <= (n << 1)) {
    74         len <<= 1;
    75         lm++;
    76     }
    77     for(int i = 1; i <= len; i++) {
    78         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1));
    79     }
    80      
    81     FFT(len, a, 1);
    82     FFT(len, b, 1);
    83     for(int i = 0; i <= len; i++) {
    84         a[i] = a[i] * b[i];
    85     }
    86     FFT(len, a, -1);
    87      
    88     for(int i = 0; i <= n; i++) {
    89         printf("%d
    ", (int)(a[n - i].x + 0.5));
    90     }
    91      
    92     return 0;
    93 }
    AC代码
  • 相关阅读:
    做一天业务员的感觉:辛苦!
    我的乒乓生涯之三浑浑噩噩的中学六年
    名菊照片(二)
    今天,同事的裤子破了
    昨晚,再一次兵败滑铁卢
    今天去世纪公园看名菊展,拍了好多照片发上来大家一起欣赏:)
    寻找上海市乒友喜欢打乒乓的朋友都进来看看
    同学给我两张f1照片:)
    又搞到几张f1照片,发上来给大家养眼
    我的乒乓生涯之四乒乓姻缘
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10248277.html
Copyright © 2011-2022 走看看