先粘一个模板。这是求高精度乘法的

#include <bits/stdc++.h>
#define maxn 1010
using namespace std;char s[maxn];typedef long long ll;
ll A[maxn], B[maxn];const int md = 998244353, G = 3;int n;ll power_mod(ll a, ll b){ll ret = 1;while(b > 0){if(b & 1)ret = ret * a % md;b >>= 1;a = a * a % md;}return ret;
}void NTT(ll A[], int n, int type){for(int i = 0, j = 0; i < n; i ++){if(i < j)swap(A[i], A[j]);for(int t = n >> 1; (j ^= t) < t; t >>= 1);}for(int k = 2; k <= n; k <<= 1){ll wn = type > 0 ? power_mod(G, (md - 1) / k) : power_mod(G, (md - 1) - (md - 1) / k);for(int i = 0; i < n; i += k){ll w = 1;for(int j = 0; j < k >> 1; j ++){ll T = w * A[i+j+(k>>1)] % md;A[i+j+(k>>1)] = (A[i+j] - T) % md;A[i+j] = (A[i+j] + T) % md;w = w * wn % md;}}}if(type < 0){ll inv = power_mod(n, md - 2);for(int i = 0; i < n; i ++)A[i] = A[i] * inv % md;}
}int main(){freopen("mul.in", "r", stdin);freopen("mul.out", "w", stdout);scanf("%s", s);int n1 = strlen(s);for(int i = n1 - 1; ~i; i --)A[n1-i-1] = s[i] ^ 48;scanf("%s", s);int n2 = strlen(s);for(int i = n2 - 1; ~i; i --)B[n2-i-1] = s[i] ^ 48;for(n = 1; n <= n1 + n2; n <<= 1);NTT(A, n, 1), NTT(B, n, 1);for(int i = 0; i < n; i ++)A[i] = A[i] * B[i] % md;NTT(A, n, -1);for(int i = 0; i < n; i ++){A[i] = (A[i] + md) % md;A[i+1] += A[i] / 10, A[i] %= 10;}while(n && A[n] == 0) n --;for(int i = n; i >= 0; i --)printf("%lld", A[i]);return 0;
}

[SDOI 2015]序列统计

取指标变成加法问题,构造生成函数F(x),F(x)的n次方就是答案。

注意指标要mod M-1

还有注意0的问题,如果x!=0就不用管数据中的0,否则需要两种情况求和(然而数据中x并不等于0我就没写)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define maxn 50010
using namespace std;
typedef long long ll;
const int md = 1004535809, G = 3;int N, M, X, S, a[maxn], Log[maxn], n;
ll F[maxn], H[maxn], ret[maxn];int p[maxn], primes, vis[maxn];ll power_mod(ll a, ll b, ll md){ll ret = 1;while(b > 0){if(b & 1) ret = ret * a % md;b >>= 1;a = a * a % md;}return ret;
}void pre_prime(){int n = 20000;for(int i = 2; i <= n; i ++){if(!vis[i])p[++ primes] = i;for(int j = 1; j <= primes; j ++){if(i * p[j] > n)break;vis[i * p[j]] = true;if(i % p[j] == 0)break;}}
}int getG(int M){pre_prime();int ret = 2;for(; ; ret ++){bool flag = true;for(int i = 1; i <= primes; i ++){if(M-1 < p[i])break;if((M-1) % p[i] == 0){if(power_mod(ret, (M - 1) / p[i], M) == 1){flag = false;break;}}}if(flag)return ret;}
}void NTT(ll A[], int n, int type){for(int i = 0, j = 0; i < n; i ++){if(i > j)swap(A[i], A[j]);for(int t = n >> 1; (j ^= t) < t; t >>= 1);}for(int k = 2; k <= n; k <<= 1){ll wn = type > 0 ? power_mod(G, (md-1)/k, md) : power_mod(G, md-1-(md-1)/k, md);for(int i = 0; i < n; i += k){ll w = 1;for(int j = 0; j < k >> 1; j ++){ll T = w * A[i+j+(k>>1)];A[i+j+(k>>1)] = (A[i+j] - T + md) % md;A[i+j] = (A[i+j] + T) % md;w = w * wn % md;}}}if(type < 0){ll inv = power_mod(n, md - 2, md);for(int i = 0; i < n; i ++)A[i] = A[i] * inv % md;}
}void CF(ll A[]){for(int i = 0; i < n; i ++)H[i] = F[i];NTT(A, n, 1), NTT(H, n, 1);for(int i = 0; i < n; i ++)A[i] = A[i] * H[i] % md;NTT(A, n, -1);for(int i = (M - 1); i < n; i ++)(A[i % (M - 1)] += A[i]) %= md, A[i] = 0;
}void power(int b){ret[0] = 1;while(b){if(b & 1)CF(ret);b >>= 1;CF(F);}
}int main(){scanf("%d%d%d%d", &N, &M, &X, &S);for(int i = 1; i <= S; i ++)scanf("%d", &a[i]);for(n = 1; n <= M; n <<= 1); n <<= 1;ll nw = 1, Gn = getG(M); for(int i = 0; i < M-1; i ++)Log[nw] = i, nw = nw * Gn % M;for(int i = 1; i <= S; i ++)if(a[i])F[Log[a[i]]] = 1;power(N);printf("%lld\n", (ret[Log[X]] + md) % md);return 0;
}

[COGS 2287]疯狂的机器人

这里有Catalan数的链接

#include <bits/stdc++.h>
#define maxn 300010
using namespace std;
typedef long long ll;
int n;
const int md = 998244353, G = 3;ll power_mod(ll a, ll b = md - 2){ll ret = 1;while(b > 0){if(b & 1)ret = ret * a % md;b >>= 1;a = a * a % md;}return ret;
}ll fac[maxn], inv[maxn], f[maxn];void NTT(ll* A, int n, int type){for(int i = 0, j = 0; i < n; i ++){if(i > j)swap(A[i], A[j]);for(int t = n >> 1; (j ^= t) < t; t >>= 1);}for(int k = 2; k <= n; k <<= 1){ll wn = power_mod(G, type > 0 ? (md-1) / k : md-1 - (md-1) / k);for(int i = 0; i < n; i += k){ll w = 1;for(int j = 0; j < k >> 1; j ++){ll T = w * A[i+j+(k>>1)] % md;A[i+j+(k>>1)] = (A[i+j] - T) % md;A[i+j] = (A[i+j] + T) % md;w = w * wn % md;}}}if(type == -1){ll inv = power_mod(n);for(int i = 0; i < n; i ++)A[i] = A[i] * inv % md;}
}int main(){freopen("crazy_robot.in", "r", stdin);freopen("crazy_robot.out", "w", stdout);scanf("%d", &n);fac[0] = inv[0] = 1;for(int i = 1; i <= 2 * n; i ++)fac[i] = fac[i-1] * i % md;inv[2 * n] = power_mod(fac[2 * n]);for(int i = 2 * n - 1; i >= 1; i --)inv[i] = inv[i+1] * (i+1) % md;for(int i = 0; i <= n; i ++){if(i & 1){f[i] = 0;continue;}f[i] = fac[i] * inv[i / 2] % md * inv[i / 2 + 1] % md * inv[i] % md;}int _N = 1;for(; _N <= n + n; _N <<= 1);NTT(f, _N, 1);for(int i = 0; i < _N; i ++)f[i] = f[i] * f[i] % md;NTT(f, _N, -1);ll ans = 0;for(int i = 0; i <= n; i ++)(ans += inv[n - i] * f[i]) %= md;cout << (ans * fac[n] % md + md) % md << endl;return 0;
}

[NOI十连测3007]卡常大法好。

#include <cstring>
#include <cstdio>
#define maxn 150010const int md = 998244353, G = 3;int R;
#define fastcall __attribute__((optimize("-Os")))
#define IL __inline__ __attribute__((always_inline))
fastcall IL int mul_mod(int a, int b){__asm__ __volatile__ ("\tmull %%ebx\n\tdivl %%ecx\n" :"=d"(R):"a"(a),"b"(b),"c"(md));return R;
}int n, N;int f[maxn], g[maxn], h[maxn], fac[maxn], inv[maxn], pw[maxn], tmp[maxn];fastcall IL int power_mod(int a, long long b = md - 2){int ret = 1;while(b > 0){if(b & 1)ret = mul_mod(ret, a);b >>= 1;a = mul_mod(a, a);}return ret;
}fastcall IL void swap(int& a, int& b){a ^= b ^= a ^= b;
}fastcall IL void NTT(int* A, int n, int type){for(int i = 0, j = 0; i < n; i ++){if(i > j)swap(A[i], A[j]);for(int t = n >> 1; (j ^= t) < t; t >>= 1);}for(int k = 2; k <= n; k <<= 1){int wn = power_mod(G, type > 0 ? (md-1)/k : (md-1)-(md-1)/k);for(int i = 0, m = k >> 1; i < n; i += k){int w = 1;for(int j = 0; j < k >> 1; j ++){int T = mul_mod(w, A[i+j+m]);A[i+j+m] = (A[i+j] - T + md) % md;A[i+j] = (A[i+j] + T) % md;w = mul_mod(w, wn);}}}if(type < 0){int inv = power_mod(n);for(int i = 0; i < n; i ++)A[i] = mul_mod(A[i], inv);}
}fastcall void Getinv(int* a, int* b, int n){if(n == 1){b[0] = power_mod(a[0]); return;}Getinv(a, b, n >> 1);memcpy(tmp, a, sizeof(a[0]) * n);NTT(tmp, n << 1, 1);NTT(b, n << 1, 1);for(int i = 0; i < n << 1; i ++)b[i] = mul_mod(b[i], (2ll - mul_mod(b[i], tmp[i]) + md) % md);NTT(b, n << 1, -1);memset(b + n, 0, sizeof(a[0]) * n);
}int F[30010][16];
int K;fastcall void cdq(int l, int r){if(l == r)return;int mid = l + r >> 1, len = r - l + 1;cdq(l, mid);for(n = 1; n <= len; n <<= 1);for(int i = 0; i < n; i ++)f[i] = h[i] = 0;for(int i = l; i <= mid; i ++)f[i-l] = mul_mod(F[i][K-1] + F[i][K], inv[i]);h[0] = 0;for(int i = 1; i < n; i ++)h[i] = mul_mod(g[i], inv[i-1]);if(n<=32) {for(int i = 0; i < n; i ++)tmp[i] = 0;for(int i = 0 ; i < n ; ++ i) {for(int j = 0 ; j <= i ; ++ j) {tmp[i] += mul_mod(h[j], f[i-j]);if(tmp[i]>=md) tmp[i] -= md;}}for(int i = 0 ; i < n ; ++ i) h[i] = tmp[i];} else {NTT(f, n, 1), NTT(h, n, 1);for(int i = 0; i < n; i ++)h[i] = mul_mod(h[i], f[i]);NTT(h, n, -1);}for(int i = mid + 1; i <= r; i ++){F[i][K] += mul_mod(h[i-l], fac[i-1]);if(F[i][K] >= md)F[i][K] -= md;}cdq(mid + 1, r);
}int main(){N = 30000;for(n = 1; n <= N; n <<= 1);fac[0] = inv[0] = 1;for(int i = 1; i <= n; i ++)fac[i] = mul_mod(fac[i - 1], i);inv[n] = power_mod(fac[n]);for(int i = n - 1; i >= 1; i --)inv[i] = mul_mod(inv[i + 1], i + 1);for(long long i = 0; i <= n; i ++)pw[i] = power_mod(2, i * (i - 1) / 2);for(int i = 1; i < n; i ++)h[i] = mul_mod(pw[i], inv[i - 1]);for(int i = 0; i < n; i ++)f[i] = mul_mod(pw[i], inv[i]);Getinv(f, g, n);n <<= 1;NTT(g, n, 1);NTT(h, n, 1);for(int i = 0; i < n; i ++)g[i] = mul_mod(g[i], h[i]);NTT(g, n, -1);for(int i = 1; i <= N; i ++)g[i] = mul_mod(g[i], fac[i - 1]);for(int i = 0; i <= N; i ++)F[i][0] = pw[i];for(int i = 1; i <= 15; i ++)K = i, cdq(0, N);static int S[20][20];S[0][0] = 1;for(int i = 1; i <= 15; i ++)for(int j = 1; j <= i; j ++){S[i][j] = mul_mod(S[i-1][j], j) + S[i-1][j-1];if(S[i][j] >= md)S[i][j] -= md;}int test, n, m;scanf("%d", &test);while(test --){scanf("%d%d", &n, &m);int ans = 0;for(int i = 0; i <= m; i ++){ans += mul_mod(mul_mod(S[m][i], F[n][i]), fac[i]);if(ans >= md)ans -= md;}printf("%d\n", ans);}return 0;
}

  

  

转载于:https://www.cnblogs.com/Candyouth/p/5437789.html

[快速数论变换 NTT]相关推荐

  1. 算法学习FFT系列(2):快速数论变换NTT bzoj3992: [SDOI2015]序列统计例题详解

    bzoj3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  2. Codeforces-1473-G. Tiles (范德蒙德卷积+快速数论变换NTT)

    题目 传送门 思路 这是题解的思路:传送门 我就再具体写写我对题解的几点理解吧. 首先,解决这个递推式的问题: ansi+1,j=∑k=1mCa+bb−k+jansi,kans_{i+1,j}=\su ...

  3. 【学习笔记】超简单的快速数论变换(NTT)(FFT的优化)(含全套证明)

    整理的算法模板合集: ACM模板 目录 一.前置知识 二.快速数论变换(NTT) 三.NTT证明(和FFT的关系) 四.NTT模板 数组形式的实现 vector形式的实现 点我看多项式全家桶(●^◡_ ...

  4. 多项式算法2:NTT(快速数论变换)

    多项式算法2:NTT(快速数论变换) 前言 前置知识 正文 前言 算法简介 上次的FFT大量使用浮点数,有精度不好控制的问题,使用可以保证精度的方法又容易超时.这里NTT是在取模的一个前提下找到一个新 ...

  5. 比FFT还容易明白的NTT(快速数论变换)

    NTT相关 一种快速数论变换算法,这种算法是以数论为基础,对样本点为的数论变换,按时间抽取的方法,得到一组等价的迭代方程,有效高速简化了方程中的计算公式·与直接计算相比,大大减少了运算次数.(见快速傅 ...

  6. NTT(快速数论变换)模板

    NTT好文 NTT快速数论变换,在acm中用于解决一类多项式卷积问题. 多项式A和多项式B求卷积后的多项式为C. 显然,如果A是n次多项式,B有m次多项式,这两个多项式都不缺项的话,乘积应为n+m次多 ...

  7. FFT 快速傅里叶变换 NTT 快速数论变换

    SDNU 1531 a*b III (FFT模板) Description 计算a乘b,多组输入(50组以内). Input 输入a b,数据范围0 <= a,b <= 10^100000 ...

  8. python蝴蝶代码_快速数论变换(NTT)及蝴蝶操作构造详解

    快速数论变换 本文不会从头开始介绍NTT算法,所以需要先了解FFT:永远在你身后:快速傅里叶变换(FFT)求解多项式乘法​zhuanlan.zhihu.com 除此之外,先简单的铺垫一些数论的概念同余 ...

  9. 【快速傅立叶变换fft数论变换ntt学习小记】

    概述 fft(快速傅立叶变换)是用来解决多项式乘法的nlog(n)算法,它的主要思想是先把多项式的多项式表达法转化成若干个二维点对(x,y)(点值),把相同x的y乘起来(计算),最后利用这些点对计算出 ...

最新文章

  1. 自然语言处理工具类数地工厂
  2. 12864输出字符c语言,大家看看该怎么改才能让12864液晶显示屏显示21个字符啊?...
  3. 设计原则交互思维,重塑产品设计
  4. SAP-SD计划行类别解析
  5. 怎样查看Oracle的数据库SID和用户名
  6. 本地随机图床api源码
  7. Laravel源码分析之Session
  8. datatables表格行内编辑的实现
  9. linux打印显示etc中的文件,Linux命令之文件内容查看(cat、tac、nl、more、less、head、tail)...
  10. C#带参数线程的操作
  11. Android Multimedia框架总结(九)Stagefright框架之数据处理及到OMXCodec过程
  12. 如何用 Lua 查询青云的主机
  13. HTML超好看的个人主页源码+支持响应式
  14. libcurl基础教程及封装(支持同步异步请求,支持多线程下载,支持https)
  15. java毕业设计软件技术课程学习系统设计与实现源码+lw文档+mybatis+系统+mysql数据库+调试
  16. 百度深度学习初级认证——已过
  17. Linux 常用命令 Updating
  18. Python批量删除微博
  19. 国内Linux内核先驱者陈莉君教授领衔,业界首个产学研 eBPF技术探索SIG成立!
  20. 【兴趣书签】为什么观测之后量子态会坍塌

热门文章

  1. python绘制3维图-1、2、3维图见过,用Python画出来的六维图见过么?
  2. python游戏编程入门 免费-Python游戏编程入门4
  3. python常用内置函数总结-Python 常用内置函数
  4. python 基础命令-Python unittest第一篇:基础入门+命令行编译
  5. python如何爬虫-如何入门 Python 爬虫?
  6. python爬虫能干啥-Python爬虫还能干什么?
  7. python学习方向-Python方向(转载)
  8. python编程 入门到实践-终于懂了python编程从入门到实践
  9. python语言及其应用-python语言及其应用
  10. python第三方库排行-Python常用第三方库总结