Mlxa

TEAMBOOK FFT в комплексных

Nov 1st, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.74 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using double_type   = double;
  3. using long_type     = long long;
  4. #define double  double_type
  5. #define long    long_type
  6. #define all(x) x.begin(), x.end()
  7. using namespace std;
  8.  
  9. struct num {
  10.     double a, b;
  11.     num(double x, double y) :
  12.         a(x),
  13.         b(y) {}
  14.     num() :
  15.         a(0),
  16.         b(0) {}
  17. };
  18. num operator+(const num &a, const num &b) {
  19.     return {a.a + b.a, a.b + b.b};
  20. }
  21. num operator-(const num &a, const num &b) {
  22.     return {a.a - b.a, a.b - b.b};
  23. }
  24. num operator*(const num &a, const num &b) {
  25.     return {a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a};
  26. }
  27. void operator/=(num &a, double k) {
  28.     a.a /= k;
  29.     a.b /= k;
  30. }
  31. //~ num operator/(const num &a, const num &b) {
  32.     //~ num c(b.a, -b.b);
  33.     //~ c = a * c;
  34.     //~ c /= b.a * b.a + b.b * b.b;
  35.     //~ return c;
  36. //~ }
  37. istream &operator>>(istream &in, num &x) {
  38.     return in >> x.a >> x.b;
  39. }
  40. ostream &operator<<(ostream &out, const num x) {
  41.     return out << x.a << ' ' << x.b;
  42. }
  43.  
  44. const int max_log   = 19;
  45. const int max_len   = 1 << max_log;
  46. const double pi = M_PIl;
  47. int rev[max_len];
  48.  
  49. void fft_init(int k) {
  50.     int n = 1 << k;
  51.     for (int i = 1; i < n; ++i) {
  52.         rev[i] = rev[i >> 1] >> 1;
  53.         rev[i] |= (i & 1) << (k - 1);
  54.     }
  55. }
  56.  
  57. void fft_dir(num *a, int k) {
  58.     int n = (1 << k);
  59.     for (int i = 0; i < n; ++i) {
  60.         if (i < rev[i]) {
  61.             swap(a[i], a[rev[i]]);
  62.         }
  63.     }
  64.     for (int h = 1; h < n; h *= 2) {
  65.         double ang = pi / h;
  66.         num mul(cos(ang), sin(ang));
  67.         for (int st = 0; st < n; st += 2 * h) {
  68.             num w(1, 0);
  69.             for (int i = st; i < st + h; ++i) {
  70.                 num x = a[i], y = a[i + h];
  71.                 a[i]        = x + w * y;
  72.                 a[i + h]    = x - w * y;
  73.                 w = w * mul;
  74.             }
  75.         }
  76.     }
  77. }
  78.  
  79. void fft_inv(num *a, int k) {
  80.     int n = (1 << k);
  81.     fft_dir(a, k);
  82.     for (int i = 0; i < n; ++i) {
  83.         a[i] /= n;
  84.     }
  85.     reverse(a + 1, a + n);
  86. }
  87.  
  88. int n, answer[max_len];
  89. char first[max_len], second[max_len];
  90. num a[max_len];
  91.  
  92. void solve(char ch) {
  93.     fill(a, a + max_len, num());
  94.     for (int i = 0; i < 2 * n; ++i) {
  95.         a[i].a = (first[i % n] == ch);
  96.     }
  97.     for (int i = 0; i < n; ++i) {
  98.         a[i].b = (second[n - 1 - i] == ch);
  99.     }
  100.     fft_dir(a, max_log);
  101.     for (int i = 0; i < max_len; ++i) {
  102.         a[i] = a[i] * a[i];
  103.     }
  104.     fft_inv(a, max_log);
  105.     for (int i = 0; i < n; ++i) {
  106.         answer[i] += round(a[n - 1 + i].b / 2);
  107.     }
  108. }
  109.  
  110. int main() {
  111. #ifdef LC
  112.     assert(freopen("input.txt", "r", stdin));
  113. #else
  114.     assert(freopen("robots.in", "r", stdin));
  115.     assert(freopen("robots.out", "w", stdout));
  116. #endif
  117.     ios::sync_with_stdio(0);
  118.     cin.tie(0);
  119.     cerr << fixed << setprecision(3);
  120.     cout << fixed << setprecision(3);
  121.    
  122.     cin >> n;
  123.     cin >> first;
  124.     cin >> second;
  125.     fft_init(max_log);
  126.     solve('A');
  127.     solve('G');
  128.     solve('C');
  129.     solve('T');
  130.     int *mx = max_element(answer, answer + n);
  131.     cout << *mx << " " << mx - answer << "\n";
  132.     return 0;
  133. }
Add Comment
Please, Sign In to add comment