Advertisement
karlicoss

FFT

Jun 14th, 2011
994
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.06 KB | None | 0 0
  1. namespace
  2. {
  3.     const double PI = std::atan(1.0) * 4;
  4.     int reverse_bits(int n, int log_n)
  5.     {
  6.         int rn = 0;
  7.         for (int i = 0; i < log_n; i++)
  8.         {
  9.             rn <<= 1;
  10.             rn += (n >> i) & 1;
  11.         }
  12.         return rn;
  13.     }
  14.     long long gcd_extended(long long a, long long b, long long &x, long long &y)
  15.     {
  16.         if (a == 0)
  17.         {
  18.             x = 0;
  19.             y = 1;
  20.             return b;
  21.         }
  22.         long long x1, y1;
  23.         long long g = gcd_extended(b % a, a, x1, y1);
  24.         x = y1 - (b / a) * x1;
  25.         y = x1;
  26.         return g;
  27.     }
  28.  
  29.     long long inverse_elem(long long a, long long m)
  30.     {
  31.         long long x, y;
  32.         gcd_extended(a, m, x, y);
  33.         return (x % m + m) % m;
  34.     }
  35.  
  36.     const long long mod = 7340033;
  37.     const long long base_prim_root = 5;
  38.     const long long base_prim_root_pow = (1 << 20);
  39. }
  40.  
  41. void fast_fourier_transform::fft_integer(vector<long long> &data, bool invert)
  42. {
  43.     vector<long long> tmp = data;
  44.     int logn = 0;
  45.     for (size_t i = 1; i < data.size(); i *= 2)
  46.         logn++;
  47.     for (size_t i = 0; i < data.size(); i++)
  48.         tmp[i] = data[reverse_bits(i, logn)];// переставляем числа чтобы избавиться от рекурсии
  49. //  for (size_t i = 0; i < data.size(); i++)
  50. //      tmp[i] %= mod; //??
  51.     data = tmp;
  52.  
  53.     for (size_t len = 2; len <= data.size(); len *= 2)//перебираем длины подотрезков
  54.     {
  55.         long long cur_prim_root = invert ? inverse_elem(base_prim_root, mod): base_prim_root;
  56.         for (long long i = len; i < base_prim_root_pow; i *= 2)
  57.             cur_prim_root = (cur_prim_root * cur_prim_root) % mod;
  58.  
  59.         for (size_t i = 0; i < data.size(); i += len) //цикл по подотрезкам
  60.         {
  61.             long long w = 1;
  62.             for (size_t j = 0; j < len / 2; j++) // по подотрезку [i, i + len)
  63.             {
  64.                 long long c = data[i + j];
  65.                 long long d = (data[i + len / 2 + j] * w) % mod;
  66.                 data[i + j] = (c + d) % mod;
  67.                 data[i + len / 2 + j] = (c - d >= 0 ? c - d : c - d + mod);
  68.                 w = (w * cur_prim_root) % mod;
  69.             }
  70.         }
  71.     }
  72.     if (invert)
  73.     {
  74.         long long n_inv = inverse_elem(data.size(), mod);
  75.         for (size_t i = 0; i < data.size(); i++)
  76.             data[i] = (data[i] * n_inv) % mod;
  77.     }
  78. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement