ACM模板库

ACM模板库


MTT

<pre><code class="language-cpp">#include &lt;bits/stdc++.h&gt; using namespace std; typedef long long ll; const int maxn = 262144; namespace MTT{ const double PI = acos(-1); struct comp{ double x, y; comp(): x(0), y(0) { } comp(const double &amp;_x, const double &amp;_y): x(_x), y(_y) { } }; inline comp operator+(const comp &amp;a, const comp &amp;b) { return comp(a.x + b.x, a.y + b.y); } inline comp operator-(const comp &amp;a, const comp &amp;b) { return comp(a.x - b.x, a.y - b.y); } inline comp operator*(const comp &amp;a, const comp &amp;b) { return comp(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); } inline comp conj(const comp &amp;a) { return comp(a.x, -a.y); } comp w[maxn + 5]; int bitrev[maxn + 5]; int mod; void fft(comp *a, const int &amp;n){ for(int i = 0; i &lt; n; i++) if (i &lt; bitrev[i]) swap(a[i], a[bitrev[i]]); for (int i = 2, lyc = n &gt;&gt; 1; i &lt;= n; i &lt;&lt;= 1, lyc &gt;&gt;= 1){ for (int j = 0; j &lt; n; j += i){ comp *l = a + j, *r = a + j + (i &gt;&gt; 1), *p = w; for(int k = 0; k &lt; (i &gt;&gt; 1); k++){ comp tmp = *r * *p; *r = *l - tmp, *l = *l + tmp; ++l, ++r, p += lyc; } } } } inline void fft_prepare(int n) { int bits = 0; while((1 &lt;&lt; bits) &lt; n) bits++; for(int i = 0; i &lt; n; i++) bitrev[i] = bitrev[i &gt;&gt; 1] &gt;&gt; 1 | ((i &amp; 1) &lt;&lt; (bits - 1)); for(int i = 0; i &lt; n; i++) w[i] = comp(cos(2 * PI * i / n), sin(2 * PI * i / n)); } inline void conv(int *x, int *y, int *z, int n) { for(int i = 0; i &lt; n; i++) (x[i] += mod) %= mod, (y[i] += mod) %= mod; static comp a[maxn + 5], b[maxn + 5]; static comp dfta[maxn + 5], dftb[maxn + 5], dftc[maxn + 5], dftd[maxn + 5]; for(int i = 0; i &lt; n; i++) a[i] = comp(x[i] &amp; 32767, x[i] &gt;&gt; 15); for(int i = 0; i &lt; n; i++) b[i] = comp(y[i] &amp; 32767, y[i] &gt;&gt; 15); fft(a, n), fft(b, n); for(int i = 0; i &lt; n; i++){ int j = (n - i) &amp; (n - 1); static comp da, db, dc, dd; da = (a[i] + conj(a[j])) * comp(0.5, 0); db = (a[i] - conj(a[j])) * comp(0, -0.5); dc = (b[i] + conj(b[j])) * comp(0.5, 0); dd = (b[i] - conj(b[j])) * comp(0, -0.5); dfta[j] = da * dc; dftb[j] = da * dd; dftc[j] = db * dc; dftd[j] = db * dd; } for(int i = 0; i &lt; n; i++) a[i] = dfta[i] + dftb[i] * comp(0, 1); for(int i = 0; i &lt; n; i++) b[i] = dftc[i] + dftd[i] * comp(0, 1); fft(a, n), fft(b, n); for(int i = 0; i &lt; n; i++){ int da = (ll)(a[i].x / n + 0.5) % mod; int db = (ll)(a[i].y / n + 0.5) % mod; int dc = (ll)(b[i].x / n + 0.5) % mod; int dd = (ll)(b[i].y / n + 0.5) % mod; z[i] = (da + ((ll)(db + dc) &lt;&lt; 15) + ((ll)dd &lt;&lt; 30)) % mod; } } } int main(){ int n, m; static int a[maxn + 5], b[maxn + 5], c[maxn + 5]; scanf("%d%d%d", &amp;n, &amp;m, &amp;MTT::mod); //n,m分别表示多项式最高次数 for(int i = 0; i &lt;= n; i++) scanf("%d", a + i); for(int i = 0; i &lt;= m; i++) scanf("%d", b + i); int tn = 1; while(tn &lt; n + m + 1) tn &lt;&lt;= 1; MTT::fft_prepare(tn); MTT::conv(a, b, c, tn); for(int i = 0; i &lt;= n + m; i++) (c[i] += MTT::mod) %= MTT::mod, printf("%d ", c[i]); printf("\n"); return 0; }</code></pre>

页面列表

ITEM_HTML