原根求解算法 && NTT算法
原根求解算法:
获取一个数\(N\)的原根\(root\)的算法
#include<bits/stdc++.h>
#define ll long long
#define IL inline
#define RG register
using namespace std;
ll prm[1000],tot,N,root;
ll Power(ll bs,ll js,ll MOD){
ll S = 1,T = bs;
while(js){
if(js&1)S = S*T%MOD;
T = T*T%MOD;
js >>= 1;
} return S;
}
IL ll GetRoot(RG ll n){
RG ll tmp = n - 1 , tot = 0;
for(RG ll i = 2; i <= sqrt(tmp); i ++){
if(tmp%i==0){
prm[++tot] = i;
while(tmp%i==0)tmp /= i;
}
}
if(tmp != 1)prm[++tot] = tmp; //质因数分解
for(RG ll g = 2; g <= n-1; g ++){
bool flag = 1;
for(RG int i = 1; i <= tot; i ++){ //检测是否符合条件
if(Power(g,(n-1)/prm[i],n) == 1)
{ flag = 0; break; }
}
if(flag)return g;
}return 0; //无解
}
int main(){
cin >> N;
root = GetRoot(N);
cout<<root<<endl;
return 0;
}
快速数论变换算法:
计算多项式\(f_1*f_2\)在模\(P\) (\(P\)为质数) 意义下的卷积。
讲真的,只要把\(FFT\)的单位复数根换成原根就行了。
注意要提前用上面的算法把模数的原根算出来。
#define mod 998244353 //使用NTT需要保证模数mod 为质数
const ll pr = 3;
//3是998244353的原根,在比赛中请用上面那个算法提前算出....
ll f1[_],f2[_],U,V;
ll wn[50],R[_],N,M,n,m,l,ans[_];
IL ll Power(RG ll bs,RG ll js){
RG ll S = 1 , T = bs;
while(js){if(js&1)S=S*T%mod; T=T*T%mod; js>>=1;}
return S;
}
IL void GetWn(){
//需要计算floor(log n)个原根
for(RG int i = 0; i <= 25; i ++){
RG ll tt = 1<<i;
wn[i] = Power(pr,(mod-1)/tt);
}return;
}
IL void NTT(RG ll P[],RG int opt){
for(RG int i = 0; i < n; i ++)
if(i < R[i]) swap(P[R[i]],P[i]);
for(RG int i = 1,id = 0; i < n; i<<=1){
id ++;
for(RG int j = 0,p = i<<1; j < n; j += p){
RG ll w = 1;
for(RG int k = 0; k < i; k ++,w = w*wn[id]%mod){
U = P[j+k]; V = w*P[j+k+i];
P[j+k] = (U+V)%mod; P[j+k+i] = ((U-V)%mod+mod)%mod;
}
}
}
if(opt == -1){
//caution:反转时是从1开始 for !!!!!
for(RG int i = 1; i < n/2; i ++)swap(P[i],P[n-i]);
RG ll inv = Power(n,mod-2);
for(RG int i = 0; i < n; i ++)P[i] = P[i]%mod*inv%mod;
}return;
}
int main(){
//读入数据:
cin >> N >> M;
for(RG int i = 0; i <= N; i ++)cin >> f1[i];
for(RG int i = 0; i <= M; i ++)cin >> f2[i];
//NTT计算:
m = N+M; l = 0;
for(n = 1; n <= m; n<<=1) ++ l;
for(RG int i = 0; i < n; i ++)
R[i] = (R[i>>1]>>1) | ((i&1)<<(l-1));
GetWn();
NTT(f1,1); NTT(f2,1);
for(RG int i = 0; i < n; i ++)f1[i] = f1[i]*f2[i]%mod;
NTT(f1,-1);
//转移答案:
for(RG int i = 0; i <= m; i ++)ans[i] = f1[i];
for(RG int i = 0; i <= m; i ++)cout<<ans[i]<<" ";
return 0;
}
原根求解算法 && NTT算法的更多相关文章
- PCB仿真软件与电磁场求解器的算法
1. 简介 目前商业化的PCB仿真软件主要有: Cadence公司的Sigrity.Ansys公司的SIwave/HFSS.CST公司的CST.Mentor公司的HyperLynx.Polor公司的S ...
- LP线性规划求解 之 单纯形 算法
LP线性规划求解 之 单纯形 算法 认识-单纯形 核心: 顶点旋转 随机找到一个初始的基本可行解 不断沿着可行域旋转(pivot) 重复2,直到结果不能改进为止 案例-过程 以上篇的case2的松弛型 ...
- GMM算法k-means算法的比较
1.EM算法 GMM算法是EM算法族的一个具体例子. EM算法解决的问题是:要对数据进行聚类,假定数据服从杂合的几个概率分布,分布的具体参数未知,涉及到的随机变量有两组,其中一组可观测另一组不可观测. ...
- 简单易学的机器学习算法——EM算法
简单易学的机器学习算法——EM算法 一.机器学习中的参数估计问题 在前面的博文中,如“简单易学的机器学习算法——Logistic回归”中,采用了极大似然函数对其模型中的参数进行估计,简单来讲即对于一系 ...
- 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)
一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...
- 理解Liang-Barsky裁剪算法的算法原理
0.补充知识向量点积:结果等于0, 两向量垂直; 结果大于0, 两向量夹角小于90度; 结果小于0, 两向量夹角大于90度.直线的参数方程:(x1, y1)和(x2, y2)两点确定的直线, 其参数方 ...
- 经典算法 KMP算法详解
内容: 1.问题引入 2.暴力求解方法 3.优化方法 4.KMP算法 1.问题引入 原始问题: 对于一个字符串 str (长度为N)和另一个字符串 match (长度为M),如果 match 是 st ...
- 经典算法 Manacher算法详解
内容: 1.原始问题 =>O(N^2) 2.Manacher算法 =>O(N) 1.原始问题 Manacher算法是由题目“求字符串中长回文子串的长度”而来.比如 abcdcb 的 ...
- 最小生成树(Prim算法+Kruskal算法)
什么是最小生成树(MST)? 给定一个带权的无向连通图,选取一棵生成树(原图的极小连通子图),使生成树上所有边上权的总和为最小,称为该图的最小生成树. 求解最小生成树的算法一般有这两种:Prim算法和 ...
随机推荐
- 一、scrapy的下载安装---Windows(安装软件太让我伤心了)
写博客就和笔记一样真的很有用,你可以随时的翻阅.爬虫的爬虫原理与数据抓取.非结构化与结构化数据提取.动态HTML处理和简单的图像识别已经学完,就差整理博客了 开始学习scrapy了,所以重新建了个分类 ...
- LeetCode - 307. Range Sum Query - Mutable
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- laravel5.4+vue+vux+element的环境搭配
最近因为项目的需要,需要搭配一个这样的环境.之前做过的东西没有这样用过,在网上找了半天不是过于简单就是根本行不通,自己踩了半天的坑,终于搭配成功. 首先下载laravel5.4,直接去官网一键安装包或 ...
- 浅谈format格式化输出
什么是format? 相对于基本格式化输出采用"%"的方法,format的功能强大,该函数把字符串当一个模板,通过传入的参数进行格式化,并且使用大括号"{}"作 ...
- object类的equals方法简介 & String类重写equals方法
object类中equals方法源码如下所示 public boolean equals(Object obj) { return this == obj; } Object中的equals方法是直接 ...
- bzoj 2217 [Poi2011]Lollipop 乱搞 贪心
2217: [Poi2011]Lollipop Time Limit: 15 Sec Memory Limit: 64 MBSec Special JudgeSubmit: 383 Solved ...
- Flask從入門到入土(二)——請求响应與Flask扩展
———————————————————————————————————————————————————————————— 一.程序和請求上下文 Flask從客戶端收到請求時,要讓視圖函數能訪問一些對象 ...
- 算法提高 矩阵乘法 区间DP
这是神题,n <= 1000,如果是极限数据普通的n^3区间DP怎么可能过?可偏偏就过了. 刘汝佳大哥的训练指南上面说的存在nlgn的算法解决矩阵链乘问题,可是百度都找不到.... AC代码 # ...
- 【视频编解码·学习笔记】8. 熵编码算法:基本算法列举 & 指数哥伦布编码
一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H ...
- Spring 中@NotNull, @NotEmpty和@NotBlank之间的区别是什么?
简述三者区别 @NotNull://CharSequence, Collection, Map 和 Array 对象不能是 null, 但可以是空集(size = 0). @NotEmpty://Ch ...