【模板】快速数论变换ntt(long long版)
2016-10-13 09:04
337 查看
快速数论变换ntt(long long版)
const LL P = 50000000001507329LL; //190734863287 * 2 ^ 18 + 1//const int P = 1004535809LL; //479 * 2 ^ 21 + 1
//const int P = 1004535809; // 119 * 2 ^ 23 + 1
const int G = 3;
LL a
, b
;
LL wn[25];
int n;
LL mul(LL x, LL y) {
return (x * y - (LL)(x / (long double)P * y + 1e-3) * P + P) % P;
}
LL qpow(LL x, LL k, LL p) {
LL ret = 1;
while(k) {
if(k & 1) ret = mul(ret, x);
k >>= 1;
x = mul(x, x);
}
return ret;
}
void getwn() {
for(int i = 1; i <= 18; ++i) {
int t = 1 << i;
wn[i] = qpow(G, (P - 1) / t, P);
}
}
void change(LL *y, int len) {
for(int i = 1, j = len / 2; i < len - 1; ++i) {
if(i < j) swap(y[i], y[j]);
int k = len / 2;
while(j >= k) {
j -= k;
k /= 2;
}
j += k;
}
}
void NTT(LL *y, int len, int on) {
change(y, len);
int id = 0;
for(int h = 2; h <= len; h <<= 1) {
++id;
for(int j = 0; j < len; j += h) {
LL w = 1;
for(int k = j; k < j + h / 2; ++k) {
LL u = y[k];
LL t = mul(y[k+h/2], w);
y[k] = u + t;
if(y[k] >= P) y[k] -= P;
y[k+h/2] = u - t + P;
if(y[k+h/2] >= P) y[k+h/2] -= P;
w = mul(w, wn[id]);
}
}
}
if(on == -1) {
for(int i = 1; i < len / 2; ++i) swap(y[i], y[len-i]);
LL inv = qpow(len, P - 2, P);
for(int i = 0; i < len; ++i)
y[i] = mul(y[i], inv);
}
}
相关文章推荐
- 快速数论变换NTT模板
- 【模板】快速数论变换ntt
- NTT FFT 数论变换 快速傅里叶变换 模板
- 【快速数论变换NTT】AVL tree
- [NTT] 快速数论变换学习笔记
- {模板}long long快速乘?
- Sumdiv(数论综合模板题:快速分解因式+快速幂取模+约数和公式+递归二分求等比数列和)
- 数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)
- 【CF914G】Sum the Fibonacci 快速??变换模板
- POJ 1845-Sumdiv 数论 +快速幂&&筛素&&分解质因数&&求因数之和的模板
- (模板) NTT long long 版
- 快速幂的模板 (数论)
- 【数论】gcd|扩展gcd|素数筛法|快速幂|欧拉函数(各种模板)
- 【模板】【数论】快速幂和快速乘法
- 【快速傅立叶变换fft&数论变换ntt学习小记】
- 高速数论变换(NTT)
- NTT任意模数模板(+O(1)快速乘)
- bzoj3992: [SDOI2015]序列统计 快速数论变换NTT+矩阵优化
- 【模板】快速区间素数计数
- go语言快速入门:template模板(12)