[CTSC2010]性能优化 [混合基FFT]
Posted qq62c30ac77b2a7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CTSC2010]性能优化 [混合基FFT]相关的知识,希望对你有一定的参考价值。
传送门
先来复习一下普通的FFT
对于混合基FFT, 有
然后就可以分治了,rev 数组的预处理有一些奇葩
#include<bits/stdc++.h>
#define N 2000050
using namespace std;
typedef long long ll;
int read()
int x = 0, f = 1; char ch = 0;
while(!isdigit(ch)) ch = getchar(); if(ch == -) f = -1;
while(isdigit(ch)) x = x*10 + (ch-0), ch = getchar();
return x * f;
int Mod, G;
ll add(ll a, ll b) return (a + b) % Mod;
ll mul(ll a, ll b) return (a * b) % Mod;
ll power(ll a, ll b) ll ans = 1;
for(;b;b>>=1) if(b&1) ans = mul(ans, a); a = mul(a, a);
return ans;
int n, c;
ll a[N], b[N], wn[N];
int rev[N], pcnt, prim[N];
ll tp[N];
void factor(int x)
for(int i = 2; i*i <= x; i++)
while(x % i == 0) prim[++pcnt] = i, x /= i;
if(x > 1) prim[++pcnt] = x;
int getG()
factor(n);
for(int i = 2;; i++)
bool flag = true;
for(int j = 1; j <= pcnt; j++) if(power(i, n/prim[j]) == 1)
flag = false; break;
if(flag) return i;
void Reverse(int *A)
for(int i = pcnt, block = n; i >= 1; i--)
for(int idx = 0, j = 0; j < n; j += block)
for(int k = 0; k < prim[i]; k++)
for(int l = 0; l < block; l += prim[i])
tp[idx++] = A[j+k+l];
for(int j = 0; j < n; j++) A[j] = tp[j];
block /= prim[i];
void DFT(ll *a, int typ)
for(int i = 0; i < n; i++) tp[i] = a[rev[i]];
for(int i = 0; i < n; i++) a[i] = tp[i];
for(int i = 1, block = 1; i <= pcnt; i++)
int mid = block; block *= prim[i];
ll wi = wn[n/block];
for(int j = 0; j < n; j++) tp[j] = 0;
for(int j = 0; j < n; j += block)
ll wk = 1;
for(int k = 0; k < block; k++)
for(int l = k%mid, w=1; l < block; l+=mid, w = mul(w,wk))
tp[j+k] = add(tp[j+k], mul(w, a[j+l]));
wk = mul(wk, wi);
for(int j = 0; j < n; j++) a[j] = tp[j];
if(typ == -1)
reverse(a+1, a+n);
for(int i = 0, inv = power(n, Mod-2); i < n; i++) a[i] = mul(a[i], inv);
int main()
n = read(), c = read(); Mod = n+1; G = getG();
wn[0] = 1; wn[1] = G;
for(int i = 2; i < n; i++) wn[i] = mul(wn[i-1], G);
for(int i = 0; i < n; i++) a[i] = read();
for(int i = 0; i < n; i++) b[i] = read();
for(int i = 0; i < n; i++) rev[i] = i; Reverse(rev);
DFT(a, 1); DFT(b, 1);
for(int i = 0; i < n; i++) a[i] = mul(a[i], power(b[i], c));
DFT(a, -1);
for(int i = 0; i < n; i++) cout << a[i] << \\n;
return 0;
以上是关于[CTSC2010]性能优化 [混合基FFT]的主要内容,如果未能解决你的问题,请参考以下文章