MTT learning small note

This is a problem unique to cancer tumor things ...... milk NOI is not a test

Demolition coefficient FFT:


When considering doing NTT NTT modulus than the modulus ( \ (2 ^ A * b + 1 \) ) how to do?

It is easy to think of the demolition of the number of FFT.

For example, now seeking \ (A * B \) , provided \ (m = \ sqrt mo ( 2 ^ 15) \)

Then the \ (a [i] \) is split into \ (A0 [I] + A1 [I] * m \) , B [I] is split into \ (b0 [i] + b1 [i] * m \)

那么\(a[i]*b[j]=a0[i]*b0[j]+(a0[i]*b1[j]+a1[i]*b0[j])*m+(a1[i]*b1[j])*m^2\)

Since \ (a0, b1, b0, b1 \) is not the size that it will not burst precision FFT.

Then this is preferably also requires 4 (n) + 3 (reverse) = 7, unacceptable complexity.

DFT:


Start to do 4 times DFT, to do with the two of us or two.

Suppose there are two series A, B, required DFT (A) and DFT (B)

\(P=A+B*i,Q=A-B*i\)

Only do DFT P and Q can be obtained in the DFT.

\ (The DFT (Q) [Ni] = conj (the DFT (P) [I]) \) , \ (conj \) conjugate, is the coefficient of the imaginary part is inverted.

prove:

\(conj(DFT(P)[i])\)

\(=conj(\sum_{j=0}^{n-1}w_n^{ji}*(A[i]+B[i]*\sqrt{-1})\)

\(=\sum_{j=0}^{n-1}conj(w_n^{ji})*conj(A[i]+B[i]*\sqrt{-1})\)

\(=\sum_{j=0}^{n-1}w_n^{-ij}*(A[i]-B[i]*\sqrt{-1})\)

\ (= DFT (Q) [Ni] \)

Is thus obtained \ (DFT (P), DFT (Q) \)

那么\(DFT(A)=(DFT(P)+DFT(Q))*({1\over2},0),\\DFT(B)=(DFT(P)-DFT(Q))*(-1)*(0, {1\over2})\)

This thing is clearly a condition that \ (A, B \) can only have real value, otherwise it will not mess up the initiative.

IDFT:


Next is the IDFT, the same two can do together.

If \ (A, B \) , \ (A, B \) have only real value portion, provided \ (C = DFT (A) + i * DFT (B) \)

Obviously \ (IDFT (C) \) is the real part is A, B is the imaginary portion

So we use four DFT complete it!

Code:


#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i <  B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
#define db double
using namespace std;

const db pi = acos(-1);

const int mo = 1e9 + 7;

struct P {
    db x, y;
    P(db _x = 0, db _y = 0) { x = _x, y = _y;}
    P operator + (P b) { return P(x + b.x, y + b.y);}
    P operator - (P b){  return P(x - b.x, y - b.y);}
    P operator * (P b) { return P(x * b.x - y * b.y, x * b.y + y * b.x);}
};

const int nm = 1 << 18;
P w[nm]; int r[nm];
P c0[nm], c1[nm], c2[nm], c3[nm];

void dft(P *a, int n) {
    ff(i, 0, n) {
        r[i] = r[i / 2] / 2 + (i & 1) * (n / 2);
        if(i < r[i]) swap(a[i], a[r[i]]);
    } P b;
    for(int i = 1; i < n; i *= 2) for(int j = 0; j < n; j += 2 * i)
        ff(k, 0, i) b = a[i + j + k] * w[i + k], a[i + j + k] = a[j + k] - b, a[j + k] = a[j + k] + b;
}
void rev(P *a, int n) {
    reverse(a + 1, a + n);
    ff(i, 0, n) a[i].x /= n, a[i].y /= n;
}
P conj(P a) { return P(a.x, -a.y);}
void fft(ll *a, ll *b, int n) {
    #define qz(x) ((ll) round(x))
//  ff(i, 0, n) c0[i] = P(a[i], 0), c1[i] = P(b[i], 0);
//  dft(c0, n); dft(c1, n);
//  ff(i, 0, n) c0[i] = c0[i] * c1[i];
//  dft(c0, n); rev(c0, n);
//  ff(i, 0, n) a[i] = qz(c0[i].x);
    ff(i, 0, n) c0[i] = P(a[i] & 32767, a[i] >> 15), c1[i] = P(b[i] & 32767, b[i] >> 15);
    dft(c0, n); dft(c1, n);
    ff(i, 0, n) {
        P k, d0, d1, d2, d3;
        int j = (n - i) & (n - 1);
        k = conj(c0[j]);
        d0 = (k + c0[i]) * P(0.5, 0);
        d1 = (k - c0[i]) * P(0, 0.5);
        k = conj(c1[j]);
        d2 = (k + c1[i]) * P(0.5, 0);
        d3 = (k - c1[i]) * P(0, 0.5);
        c2[i] = d0 * d2 + d1 * d3 * P(0, 1);
        c3[i] = d0 * d3 + d1 * d2;
    }
    dft(c2, n); dft(c3, n); rev(c2, n); rev(c3, n);
    ff(i, 0, n) {
        a[i] = qz(c2[i].x) + (qz(c2[i].y) % mo << 30) + (qz(c3[i].x) % mo << 15);
        a[i] %= mo;
    }
}

ll a[nm], b[nm]; 

int main() {
    for(int i = 1; i < nm; i *= 2) ff(j, 0, i)
        w[i + j] = P(cos(pi * j / i), sin(pi * j / i));
    fo(i, 0, 15) a[i] = b[i] = mo - 1;
    fft(a, b, 32);
    ff(i, 0, 32) pp("%lld ", a[i]);
}

Guess you like

Origin www.cnblogs.com/coldchair/p/11129417.html