Advertisement
Mlxa

### Нерекурсивное БПФ

Feb 12th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.44 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define long ll
  5. #define all(x) begin(x), end(x)
  6.  
  7.  
  8. struct Number {
  9.     double real, imag;
  10.     Number(double a, double b) :
  11.         real(a),
  12.         imag(b) {}
  13.     Number() :
  14.         Number(0, 0) {}
  15. };
  16.  
  17. Number operator*(const Number a, const Number b) {
  18.     return Number(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real);
  19. }
  20. Number operator+(const Number &a, const Number &b) {
  21.     return Number(a.real + b.real, a.imag + b.imag);
  22. }
  23. Number operator-(const Number &a, const Number &b) {
  24.     return Number(a.real - b.real, a.imag - b.imag);
  25. }
  26. void operator/=(Number &a, int n) {
  27.     a.real /= n;
  28.     a.imag /= n;
  29. }
  30.  
  31. const int N = 1 << 21;
  32. const double PI = acos(-1);
  33. Number w[N];
  34.  
  35. void init_fft() {
  36.     w[0] = Number(1, 0);
  37.     w[1] = Number(cos(2 * PI / N), sin(2 * PI / N));
  38.     for (int i = 0; i < N; i += 1024) {
  39.         w[i] = Number(cos(2 * PI * i / N), sin(2 * PI * i / N));
  40.         for (int j = i + 1; j < i + 1024; ++j) {
  41.             w[j] = w[j - 1] * w[1];
  42.         }
  43.     }
  44. }
  45.  
  46. int rev[N];
  47.  
  48. void fft_no_rec(Number *a, int k) {
  49.     int n = 1 << k;
  50.     rev[0] = 0;
  51.     for (int i = 1; i < n; ++i) {
  52.         rev[i] = rev[i >> 1] >> 1;
  53.         if (i & 1) {
  54.             rev[i] |= 1 << (k - 1);
  55.         }
  56.     }
  57.     for (int i = 0; i < n; ++i) {
  58.         if (i < rev[i]) {
  59.             swap(a[i], a[rev[i]]);
  60.         }
  61.     }
  62.     for (int l = 1; l < n; l *= 2) {
  63.         for (int i = 0; i < n; i += 2 * l) {
  64.             for (int j = 0; j < l; ++j) {
  65.                 Number x = a[i + j], y = w[j * (N / (2 * l))] * a[i + j + l];
  66.                 a[i + j]     = x + y;
  67.                 a[i + j + l] = x - y;
  68.             }
  69.         }
  70.     }
  71. }
  72.  
  73. Number arr[N];
  74.  
  75. void fft(Number *a, int k, int type) {
  76.     int n = 1 << k;
  77.     fft_no_rec(a, k);
  78.     if (type == -1) {
  79.         reverse(a + 1, a + n);
  80.         for (int i = 0; i < n; ++i) {
  81.             a[i] /= n;
  82.         }
  83.     }
  84. }
  85.  
  86. vector<int> mul(vector<int> a, vector<int> b) {
  87.     int k = 0;
  88.     while ((1ULL << k) <= (a.size() + b.size())) {
  89.         ++k;
  90.     }
  91.     a.resize(1 << k);
  92.     b.resize(1 << k);
  93.     for (int i = 0; i < (1 << k); ++i) {
  94.         arr[i].real = a[i];
  95.         arr[i].imag = b[i];
  96.     }
  97.     fft(arr, k, 1);
  98.     for (int i = 0; i < (1 << k); ++i) {
  99.         arr[i] = arr[i] * arr[i];
  100.     }
  101.     fft(arr, k, -1);
  102.     vector<int> res(1 << k);
  103.     for (int i = 0; i < (1 << k); ++i) {
  104.         res[i] = (int)(arr[i].imag / 2 + 0.5);
  105.     }
  106.     while (res.size() && res.back() == 0) {
  107.         res.pop_back();
  108.     }
  109.     return res;
  110. }
  111.  
  112.  
  113. int main() {
  114. #ifdef LC
  115.     assert(freopen("input.txt", "r", stdin));
  116. #endif
  117.     ios::sync_with_stdio(false);
  118.     cin.tie(nullptr);
  119.    
  120.     init_fft();
  121.    
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement