整理的算法模板合集: ACM模板


目录

  • 多项式除法
  • P4512 【模板】多项式除法
  • tips
  • 还没调出来的vector版本代码

点我看多项式全家桶(●^◡_◡◡​^●)

多项式除法

P4512 【模板】多项式除法

P4512 【模板】多项式除法


按照上述思路简单实现一下就行了(

tips

注意一点,在我们每次求 limit 的时候,把范围都乘 2 ,反正乘了开大一点不会错,但是有时候不开就会 WA(比如这里多项式除法的时候 )
limit可以设成全局变量,注意每次使用limit的时候都要按照下面的格式初始化一下 limit 以及 L

就是这里:

       for(limit = 1, L = 0; limit <= (n + m) * 2; limit <<= 1) L ++ ;for(int i = 0; i < limit; ++ i) RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 4000007;
const int p = 998244353, gg = 3, ig = 332738118;
const int mod = 998244353;
int limit = 1;
int L;
int RR[N];
ll F[N], G[N], H[N], Q[N], R[N];
ll A[N], B[N], C[N];
ll gg_inv;template <typename T>void read(T &x)
{x = 0;register int f = 1;register char ch = getchar();while(ch < '0' || ch > '9') {if(ch == '-')f = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}x *= f;
}ll qpow(ll a, ll b)
{ll res = 1;while(b) {if(b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res % p;
}ll inv(ll x) {return qpow(x, mod - 2);}void NTT(ll *A, int type)
{for(int i = 0; i < limit; ++ i)if(i < RR[i])swap(A[i], A[RR[i]]);for(int mid = 1; mid < limit; mid <<= 1) {ll wn = qpow(gg, (mod - 1) / (2 * mid));if(type == -1) wn = qpow(wn, mod - 2);for(int len = mid << 1, pos = 0; pos < limit; pos += len) {ll w = 1;for(int k = 0; k < mid; ++ k, w = (w * wn) % mod){int x = A[pos + k] % mod;int y = w * A[pos + k + mid] % mod;A[pos + k] = (x + y) % mod;A[pos + k + mid] = (x - y + mod) % mod;}}}if(type == -1) {ll limit_inv = inv(limit);for(int i = 0; i < limit; ++ i) {A[i] = (A[i] * limit_inv) % mod;}}
}//多项式求逆
void get_inv(ll *A, ll *B, int deg)
{if(deg == 1) {B[0] = inv(A[0]);return ;}get_inv(A, B, (deg + 1) >> 1);for(limit = 1, L = 0; limit <= (deg << 1) * 2; limit <<= 1) L ++ ;for(int i = 0; i < limit; ++ i) {RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));C[i] = (i < deg ? A[i] : 0);}NTT(C, 1), NTT(B, 1);for(int i = 0; i <= limit; ++ i)B[i] = (2ll - C[i] * B[i] % mod + mod) % mod * B[i] % mod;NTT(B, -1);fill(B + deg, B + limit, 0);
}void poly_mul(ll *a, ll *b, int n, int m)
{for(limit = 1, L = 0; limit <= (n + m) * 2; limit <<= 1) L ++ ;for(int i = 0; i < limit; ++ i) {RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));}NTT(a, 1);NTT(b, 1);for(int i = 0; i < limit; ++ i ) {a[i] = a[i] * b[i] % mod;}NTT(a, -1);
}ll t[N], Fr[N], Gr[N], Qr[N], Gr_inv[N];
int n, m;int main()
{//gg_inv = inv(gg);read(n);read(m);//n ++ , m ++ ;for(int i = 0; i <= n; ++ i) read(F[i]), Fr[n - i] = F[i];//读入F,求翻转的Fr数组(可以直接手动翻转hhh)for(int i = 0; i <= m; ++ i) read(G[i]), Gr[m - i] = G[i];//读入G,求翻转的Gr数组for(int i = n - m + 2; i <= m; ++ i) Gr[i] = 0;//Gr数组应该只有n - m项get_inv(Gr, Gr_inv, n - m + 1);//求逆poly_mul(Fr, Gr_inv, n, n - m);//乘起来得到Qrfor(int i = 0; i <= n - m; ++ i) Q[i] = Fr[n - m - i];//求Qr数组的翻转既是要求的Q数组(商)for(int i = 0; i <= n - m; ++ i) printf("%lld ", Q[i]);puts("");poly_mul(G, Q, m, n - m);//R(x) = F(x) - G(x)Q(x);小于m项for(int i = 0; i < m; ++ i) R[i] = (F[i] - G[i] + mod) % mod;for(int i = 0; i < m; ++ i)printf("%lld ", R[i]);puts("");return 0;
}

还没调出来的vector版本代码

//#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;const int N = 3000007;
const int p = 998244353, gg = 3, ig = 332738118, img = 86583718;
const int mod = 998244353;template <typename T>void read(T &x)
{x = 0;register int f = 1;register char ch = getchar();while(ch < '0' || ch > '9') {if(ch == '-')f = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}x *= f;
}int qpow(int a, int b)
{int res = 1;while(b) {if(b & 1) res = 1ll * res * a % mod;a = 1ll * a * a % mod;b >>= 1;}return res;
}namespace Poly
{#define mul(x, y) (1ll * x * y >= mod ? 1ll * x * y % mod : 1ll * x * y)#define minus(x, y) (1ll * x - y < 0 ? 1ll * x - y + mod : 1ll * x - y)#define plus(x, y) (1ll * x + y >= mod ? 1ll * x + y - mod : 1ll * x + y)#define ck(x) (x >= mod ? x - mod : x)//取模运算太慢了typedef vector<int> poly;const int G = 5;const int inv_G = qpow(G, mod - 2);int RR[N], deer[2][19][N], inv[N];void init(const int t) {//预处理出来NTT里需要的w和wn,砍掉了一个log的时间for(int p = 1; p <= t; ++ p) {int buf1 = qpow(G, (mod - 1) / (1 << p));int buf0 = qpow(inv_G, (mod - 1) / (1 << p));deer[0][p][0] = deer[1][p][0] = 1;for(int i = 1; i < (1 << p); ++ i) {deer[0][p][i] = 1ll * deer[0][p][i - 1] * buf0 % mod;//逆deer[1][p][i] = 1ll * deer[1][p][i - 1] * buf1 % mod;}}inv[1] = 1;for(int i = 2; i <= (1 << t); ++ i)inv[i] = 1ll * inv[mod % i] * (mod - mod / i) % mod;}int NTT_init(int n) {//快速数论变换预处理int limit = 1, L = 0;while(limit < n) limit <<= 1, L ++ ;for(int i = 0; i < limit; ++ i)RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));return limit;}void NTT(poly &A, int type, int limit) {//快速数论变换A.resize(limit);for(int i = 0; i < limit; ++ i)if(i < RR[i])swap(A[i], A[RR[i]]);for(int mid = 2, j = 1; mid <= limit; mid <<= 1, ++ j) {int len = mid >> 1;for(int pos = 0; pos < limit; pos += mid) {int *wn = deer[type][j];for(int i = pos; i < pos + len; ++ i, ++ wn) {int tmp = 1ll * (*wn) * A[i + len] % mod;A[i + len] = ck(A[i] - tmp + mod);A[i] = ck(A[i] + tmp);}}}if(type == 0) {for(int i = 0; i < limit; ++ i)A[i] = 1ll * A[i] * inv[limit] % mod;}}poly poly_mul(poly A, poly B, int deg = 0) {//多项式乘法if(deg == 0) deg = A.size() + B.size() - 1;int limit = NTT_init(deg);poly C(limit);NTT(A, 1, limit);NTT(B, 1, limit);for(int i = 0; i < limit; ++ i)C[i] = 1ll * A[i] * B[i] % mod;NTT(C, 0, limit);C.resize(deg);return C;}poly poly_inv(poly &f, int deg) {//多项式求逆if(deg == 1)return poly(1, qpow(f[0], mod - 2));poly A(f.begin(), f.begin() + deg);poly B = poly_inv(f, (deg + 1) >> 1);int limit = NTT_init(deg << 1);NTT(A, 1, limit), NTT(B, 1, limit);for(int i = 0; i < limit; ++ i)A[i] = B[i] * (2 - 1ll * A[i] * B[i] % mod + mod) % mod;NTT(A, 0, limit);A.resize(deg);return A;}poly poly_dev(poly f) {//多项式求导int n = f.size();for(int i = 1; i < n; ++ i) f[i - 1] = 1ll * f[i] * i % mod;return f.resize(n - 1), f;//f[0] = 0,这里直接扔了,从1开始}poly poly_idev(poly f) {//多项式求积分int n = f.size();for(int i = n - 1; i ; -- i) f[i] = 1ll * f[i - 1] * inv[i] % mod;return f[0] = 0, f;}poly poly_ln(poly f, int deg) {//多项式求对数poly A = poly_idev(poly_mul(poly_dev(f), poly_inv(f, deg)));return A.resize(deg), A;}poly poly_exp(poly &f, int deg) {//多项式求指数if(deg == 1)return poly(1, 1);poly B = poly_exp(f, (deg + 1) >> 1);B.resize(deg);poly lnB = poly_ln(B, deg);for(int i = 0; i < deg; ++ i)lnB[i] = ck(f[i] - lnB[i] + mod);int limit = NTT_init(deg << 1);//n -> n^2NTT(B, 1, limit), NTT(lnB, 1, limit);for(int i = 0; i < limit; ++ i)B[i] = 1ll * B[i] * (1 + lnB[i]) % mod;NTT(B, 0, limit);B.resize(deg);return B;}poly poly_sqrt(poly &f, int deg) {//多项式开方if(deg == 1) return poly(1, 1);poly A(f.begin(), f.begin() + deg);poly B = poly_sqrt(f, (deg + 1) >> 1);poly IB = poly_inv(B, deg);int limit = NTT_init(deg << 1);NTT(A, 1, limit), NTT(IB, 1, limit);for(int i = 0; i < limit; ++ i)A[i] = 1ll * A[i] * IB[i] % mod;NTT(A, 0, limit);for(int i =0; i < deg; ++ i)A[i] = 1ll * (A[i] + B[i]) * inv[2] % mod;A.resize(deg);return A;}poly poly_pow(poly f, int k) {//多项式快速幂f = poly_ln(f, f.size());for(auto &x : f) x = 1ll * x * k % mod;return poly_exp(f, f.size());}poly poly_cos(poly f, int deg) {//多项式三角函数(cos)poly A(f.begin(), f.begin() + deg);poly B(deg), C(deg);for(int i = 0; i < deg; ++ i)A[i] = 1ll * A[i] * img % mod;B = poly_exp(A, deg);C = poly_inv(B, deg);int inv2 = qpow(2, mod - 2);for(int i = 0; i < deg; ++ i)A[i] = 1ll * (1ll * B[i] + C[i]) % mod * inv2 % mod;return A;}poly poly_sin(poly f, int deg) {//多项式三角函数(sin)poly A(f.begin(), f.begin() + deg);poly B(deg), C(deg);for(int i = 0; i < deg; ++ i)A[i] = 1ll * A[i] * img % mod;B = poly_exp(A, deg);C = poly_inv(B, deg);int inv2i = qpow(img << 1, mod - 2);for(int i = 0; i < deg; ++ i)A[i] = 1ll * (1ll * B[i] - C[i] + mod) % mod * inv2i % mod;return A;}poly poly_arcsin(poly f, int deg) {poly A(f.size()), B(f.size()), C(f.size());A = poly_dev(f);B = poly_mul(f, f);for(int i = 0; i < deg; ++ i)B[i] = minus(mod, B[i]);B[0] = plus(B[0], 1);C = poly_sqrt(B, deg);C = poly_inv(C, deg);C = poly_mul(A, C);C = poly_idev(C);return C;}poly poly_arctan(poly f, int deg) {poly A(f.size()), B(f.size()), C(f.size());A = poly_dev(f);B = poly_mul(f, f);B[0] = plus(B[0], 1);C = poly_inv(B, deg);C = poly_mul(A, C);C = poly_idev(C);return C;}void poly_division(poly F, poly G, poly &Q, poly &R, int n, int m)//多项式除法{poly Fr(n), Gr(m);for(int i = 0; i <= n; ++ i) Fr[n - i] = F[i];for(int i = 0; i <= m; ++ i) Gr[m - i] = G[i];for(int i = n - m + 2; i <= m; ++ i) Gr[i] = 0;poly Gr_inv = poly_inv(Gr, (n - m + 1) * 2);Fr = poly_mul(Fr, Gr_inv, n * 2);for(int i = 0; i <= n - m; ++ i) Q[i] = Fr[n - m - i];for(int i = 0; i <= n - m; ++ i) printf("%lld ", Q[i]);puts("");G = poly_mul(G, Q, n * 2);for(int i = 0; i < m; ++ i) R[i] = (F[i] - G[i] + mod) % mod;for(int i = 0; i < m; ++ i)printf("%lld ", R[i]);puts("");}
}using Poly::poly;
using Poly::poly_arcsin;
using Poly::poly_arctan;
using Poly::poly_division;int n, m, x, k, type;char s[N];int main()
{Poly::init(18);//2^21 = 2,097,152,根据题目数据多项式项数的大小自由调整,注意大小需要跟deer数组同步(21+1=22)read(n), read(m);poly F(n), G(m), Q(n + m), R(n + m);for(int i = 0; i <= n; ++ i) read(F[i]);for(int i = 0; i <= m; ++ i) read(G[i]);poly_division(F, G, Q, R, n, m);/*for(int i = 0; i <= n - m; ++ i)printf("%lld ", Q[i]);puts("");for(int i = 0; i < m; ++ i)printf("%lld ", R[i]);*/return 0;
}

【学习笔记】超简单的多项式除法(含完整证明)相关推荐

  1. Unity学习笔记--超简单:两个游戏对象直接用线连接(UI和世界坐标下均可)

    目录 UI用 效果图 UI代码示例 挂载示例 世界坐标用 挂载示例 效果图 世界坐标代码示例 我们分两种情况,一种是UI上连线,一种是世界坐标下连线. UI用 效果图 UI代码示例 public cl ...

  2. 论文学习笔记: Learning Multi-Scale Photo Exposure Correction(含pytorch代码复现)

    论文学习笔记: Learning Multi-Scale Photo Exposure Correction--含pytorch代码复现 本章工作: 论文摘要 训练数据集 网络设计原理 补充知识:拉普 ...

  3. python自训练神经网络_tensorflow学习笔记之简单的神经网络训练和测试

    本文实例为大家分享了用简单的神经网络来训练和测试的具体代码,供大家参考,具体内容如下 刚开始学习tf时,我们从简单的地方开始.卷积神经网络(CNN)是由简单的神经网络(NN)发展而来的,因此,我们的第 ...

  4. VC学习笔记:简单绘图

    VC学习笔记:简单绘图 SkySeraph Oct.29th 2009  HQU Email-zgzhaobo@gmail.com  QQ-452728574 Latest Modified Date ...

  5. STM32F429I-Discovery学习笔记--(1)简单上手和官方例程的下载与使用

    STM32F429I-Discovery学习笔记–(1)简单上手和官方例程的下载与使用 到手测试 收到开发板后我们要首先检查一下外观有没有磕碰破损,排针是否发生弯折,重要的是看一下JP3和CN4处的跳 ...

  6. Tensorflow2学习笔记:简单灰度图分类

    Tensorflow2学习笔记:简单灰度图分类 相关介绍 实验环境 实验步骤 导入相关库 导入数据集 浏览数据 预处理数据 构建模型 设置层 编译模型 训练模型 向模型馈送数据 评估准确率 进行预测 ...

  7. PointNet学习笔记(二)——支撑材料(理论证明)

    PointNet学习笔记(二)--支撑材料(理论证明) 这一部分记录了PointNet中两个定理的证明和博主的学习笔记.具体的定理可以参见论文学习笔记,这里仅给出证明.更新于2018.10.12. 文 ...

  8. Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例

    在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...

  9. 【Python学习笔记】简单调用百度API应用

    #本文一切代码及理论均来自于郑秋生.夏敏捷二位老师主编<Python项目案例发 从入门到实践>一书,本人仅做微改.创作本文的目的仅为总结本人的学习过程和成果,借此巩固.可能存在许多疏漏之处 ...

最新文章

  1. Nilearn教程系列(3)-ICA静息功能磁共振成像的分组分析:CanICA
  2. 9-Building FIP images with support for Trusted Board Boot
  3. Go语言 Yaml编码和解码
  4. 小程序禁用ios 左右滑动_如何在使用应用程序时禁用iOS控制中心
  5. spring学习(40):注入数组类型
  6. 20分钟快速了解Redis
  7. 致谢!华为全联接2020精彩回顾
  8. OpenShift 4 之在不同的项目之间推送Image
  9. python input文字_Python-8-讓使用者輸入文字/input()用法
  10. 中国区Azure基本实例更新
  11. C++ Boost库 多线程 线程锁mutex lock_guard 、unique_lock、upgrade_lock、upgrade_to_unique_lock实例
  12. python远程执行shell脚本文件_python SSH模块登录,远程机执行shell命令实例解析
  13. 计算机绘图 精品课程,机械制图与计算机绘图精品课程建设与成效.doc
  14. 简析FUP LB5CM/LB6CM 落地式低速大容量冷冻离心机
  15. xtu 1370 ball
  16. 怎么在服务器上接无线路由器,交换机怎么用 交换机接无线路由器设置教程【详解】...
  17. 深圳医保社保的使用方法
  18. 魔百盒cm201-1YS不识别
  19. Visualising Residuals
  20. RTSP播放器网页web无插件直播流媒体音视频播放器EasyPlayer-RTSP-Android解码获取视频帧的方法

热门文章

  1. 一文了解点特征直方图
  2. Ret2Libc(1) (有system、/bin/sh)绕过NX、ASLR
  3. 临江市领导参观视察域乎 —— 积极探索、稳妥布局“区块链+农业”
  4. Yii2掉index.php?r=
  5. IT运维人员追女友必备神器之运维开发实战程序案例
  6. 进行博客博文管理的设计
  7. android Toast大全(五种情形)建立属于你自己的Toast
  8. CentOS 4.6 中 yum 的使用
  9. android 表示空字符串,Android Logcat获取空字符串时非常奇怪的行为
  10. oracle触发器 条件,oracle触发器的定义和使用