咕咕咕 先开个坑(其实是存模板来了)

一些特别简单的前置东西qwq

复数的计算

复数相加:向量相加,复数相乘。复数相乘:模长相乘,旋转量相加(就是复平面坐标轴逆时针旋转的角度)

(当然也可以直接使用complex类,.real()即取实数部分)

单位根

主n次单位根:\(w_n=e^{2\pi i/n}\)

n个n次单位复数根可以用\(w_n^0,w_n^1,...,w_n^{n-1}\)

性质

  • n次单位根的次幂还是n次单位根
  • \(w_n^n=1\),n为偶数时\(w_n^{n/2}=-1\)
  • \(\sum_{i=0}^{n-1}w_n^i=0\)(证明方式:等比数列求和)
  • 全部单位根将复平面上单位圆n等分
  • \(w_{2n}^{2k}=w_n^k\)
  • \(w_n^{k+\frac{n}{2}}=-w_n^k\)

原根

阶的定义:

设a,p是整数,a和p互素,那么:

使\(a^n\equiv1\pmod p\)成立的最小正整数n叫做a模p的阶。

原根的定义:

原根,是一个数学符号。设m是正整数,a是整数,若a模m的阶等于\(\phi\)(m),则称a为模m的一个原根。

原根的性质:

  • 对于正整数x,只有\(x=2,4,p^a,2\times p^a\),p为奇素数,a>=1的时候才存在原根。
  • \(a^1,a^2,a^3,...,a^{\phi(m)}\)在模p的时候都不相同(可以推得它构成了一个长度为\(\phi(m)\)的循环节)
  • 对于m的原根g,满足gi(mod p)(0<=i<=p-2)与1到p-1一一对应.
  • 若m有原根,那么它的原根个数为\(\phi(\phi(m))\)。(具体证明蒟蒻不是特别会qwq,上课没听懂)

对于m的情况最为常用。在这种情况下,0~m-1中每一个数都可以对应一个\(a^x\),这就相当于模意义下取对数(离散对数)。我们可以化乘为加。或者快速地计算一个数的若干次幂。

判断一个数a是不是m的原根

即判断是否不存在\(1<=x<\phi(m)\)。由于\(a^{\phi(m)}\equiv \pmod m\),我们只需要判断x为\(\phi(m)\)的因数的情况就可以了,时间复杂度\(O(sqrt(m)log m)\)

实际上,对于\(\phi(m)\)的每种质因数p_i判断\(\frac{\phi(m)}{p_i}\)也是等价的。

求出原根后,用暴力或者BSGS就可以求出来一个数的对数。

ps.一个数的原根是很多的,我们可以从小到大判断,或者随机化选取数字判断。

完全是背模板的FFT

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MAXN 2700010
using namespace std;
int n,m,cnt;
int r[MAXN];
const double PI=acos(-1.0);
struct complex
{
double x,y;
complex(double xx=0,double yy=0){x=xx,y=yy;}
}a[MAXN],b[MAXN];
complex operator +(complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
complex operator -(complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
complex operator *(complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
inline void fft(complex *p,int opt)
{
for(int i=0;i<n;i++) if(i<r[i]) swap(p[i],p[r[i]]);
for(int i=1;i<n;i<<=1)
{
complex W=complex(cos(PI/i),opt*sin(PI/i));
for(int r=i<<1,j=0;j<n;j+=r)
{
complex w(1,0);
for(int k=0;k<i;k++,w=w*W)
{
complex X=p[j+k],Y=w*p[j+i+k];
p[j+k]=X+Y;
p[j+i+k]=X-Y;
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) scanf("%lf",&a[i]);
for(int i=0;i<=m;i++) scanf("%lf",&b[i]);
m+=n;
for(n=1;n<=m;n<<=1) ++cnt;
for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(cnt-1));
fft(a,1);
fft(b,1);
for(int i=0;i<=n;i++) a[i]=a[i]*b[i];
fft(a,-1);
for(int i=0;i<=m;i++) printf("%d ",(int)(a[i].x/n+0.5));
return 0;
}

继续背模板的NTT

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define mod 998244353
#define MAXN 5000010
using namespace std;
int n,m,N,M,gr=3,l;
int r[MAXN],a[MAXN],b[MAXN];
inline int fpow(int x,int y)
{
int cur_ans=1;
while(y)
{
if(y&1) cur_ans=1ll*cur_ans*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return cur_ans;
}
inline void ntt(int *P,int opt)
{
for(int i=0;i<N;i++)
if(i<r[i])
swap(P[i],P[r[i]]);
for(int i=1;i<N;i<<=1)
{
int W=fpow(gr,(mod-1)/(i*2));
for(int p=i<<1,j=0;j<N;j+=p)
{
int w=1;
for(int k=0;k<i;k++,w=1ll*w*W%mod)
{
int X=P[j+k],Y=1ll*w*P[j+k+i]%mod;
P[j+k]=(X+Y)%mod,P[j+k+i]=(X+mod-Y)%mod;
}
}
}
if(opt==-1) reverse(&P[1],&P[N]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) scanf("%d",&a[i]);
for(int i=0;i<=m;i++) scanf("%d",&b[i]);
N=n,M=m;
M+=N;
for(N=1;N<=M;N<<=1) l++;
for(int i=0;i<N;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
ntt(a,1),ntt(b,1);
for(int i=0;i<N;i++) a[i]=1ll*a[i]*b[i]%mod;
ntt(a,-1);
for(int i=0,inv=fpow(N,mod-2);i<=M;i++) a[i]=1ll*a[i]*inv%mod;
for(int i=0;i<=M;i++) printf("%d ",a[i]); puts("");
return 0;
}

所以说分治FFT是个什么东西

多项式求逆

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define gr 3
#define MAXN 1000010
#define mod 998244353
using namespace std;
int n,m,N,M,l;
int r[MAXN],A[MAXN],B[MAXN],X[MAXN],Y[MAXN];
inline int fpow(int x,int y)
{
int cur_ans=1;
while(y)
{
if(y&1) cur_ans=1ll*cur_ans*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return cur_ans;
}
inline void ntt(int *P,int opt,int len)
{
l=0;
for(N=1;N<len;N<<=1) l++;
for(int i=0;i<N;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<N;i++)
if(i<r[i])
swap(P[i],P[r[i]]);
for(int i=1;i<N;i<<=1)
{
int W=fpow(gr,(mod-1)/(i<<1));
for(int j=0,p=i<<1;j<N;j+=p)
{
int w=1;
for(int k=0;k<i;k++,w=1ll*w*W%mod)
{
int X=P[j+k],Y=1ll*w*P[j+k+i]%mod;
P[j+k]=(X+Y)%mod,P[j+k+i]=(X+mod-Y)%mod;
}
}
}
if(opt==-1) reverse(&P[1],&P[N]);
}
inline void get_inv(int *a,int *b,int len)
{
if(len==1){b[0]=fpow(a[0],mod-2)%mod;return;}
get_inv(a,b,len>>1);
for(int i=0;i<len;i++) A[i]=a[i],B[i]=b[i];
ntt(A,1,len<<1),ntt(B,1,len<<1);
for(int i=0;i<(len<<1);i++) A[i]=1ll*A[i]*B[i]%mod*B[i]%mod;
ntt(A,-1,len<<1);
for(int i=0,inv=fpow(N,mod-2);i<N;i++) A[i]=1ll*A[i]*inv%mod;
for(int i=0;i<len;i++) b[i]=2*b[i]%mod;
for(int i=0;i<len;i++) b[i]=(b[i]+mod-A[i])%mod;
for(int i=0;i<(len<<1);i++) A[i]=B[i]=0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&X[i]);
for(N=1;N<n;N<<=1);
get_inv(X,Y,N);
for(int i=0;i<n;i++) printf("%d ",Y[i]); puts("");
return 0;
}

多项式开根

多项式除法

多项式对数

多项式指数

多项式快速幂

OI多项式 简单学习笔记的更多相关文章

  1. OI数学 简单学习笔记

    基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. PART1 数论部分 最大公约数 对于正整数x,y,最大的能同时整除它们的数称为最大公约数 常用的:\(lcm(x,y)=xy\ ...

  2. OI图论 简单学习笔记

    网络流另开了一个专题,所以在这里就不详细叙述了. 图 一般表示为\(G=(V,E)\),V表示点集,E表示边集 定义图G为简单图,当且仅当图G没有重边和自环. 对于图G=(V,E)和图G2=(V2,E ...

  3. OI网络流 简单学习笔记

    持续更新! 基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. ..怎么说呢,最基础的模板我就我不说了吧qwq,具体可以参考一下这位大佬写的博客:最大流,最小割,费用流 费用流 跑 ...

  4. OI计算几何 简单学习笔记

    学习平面几何,首先我们要会熟练地应用向量,其次也要知道一些基本的几何知识.(其实看看数学课本就可以了吧) 因为是看的蓝书,所以很多东西做了引用.(update:还参考了赵和旭dalao的讲义) 下面先 ...

  5. OI字符串 简单学习笔记

    持续更新qwq KMP 其实是MP啦qwq 就是先自己匹配自己得到状态图,然后再在上面进行模式串的匹配. nxt数组返回的是以该节点结尾的,最长的,在前面出现过的,不相交的,字符串的最靠右的,末位位置 ...

  6. FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅲ

    第三波,走起~~ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ 单位根反演 今天打多校时 1002 被卡科技了 ...

  7. Log4j简单学习笔记

    log4j结构图: 结构图展现出了log4j的主结构.logger:表示记录器,即数据来源:appender:输出源,即输出方式(如:控制台.文件...)layout:输出布局 Logger机滤器:常 ...

  8. Linux——帮助命令简单学习笔记

    Linux帮助命令简单学习笔记: 一: 命令名称:man 命令英文原意:manual 命令所在路径:/usr/bin/man 执行权限:所有用户 语法:man [命令或配置文件] 功能描述:获得帮助信 ...

  9. <<C++标准程序库>>中的STL简单学习笔记

    0. 内容为个人学习笔记, 仅供参考, 如有错漏, 欢迎指正! 1. STL中的所有组件都是由模板构成的, 所以其元素可以是任意型别的. 组件有: - 容器: 管理某类对象的集合. 不同的容器有各自的 ...

随机推荐

  1. Centos(64位)安装Hbase详细步骤

    HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利用了Google文件 ...

  2. [转帖]小米手环采用RISC-V 指令集芯片

    小米手环4或用“黄山一号”芯片,雷军再回前线,未来走向如何 静心科技 06-1111:19 忘记来源地址了 不过国内的很多东西都是有中国特色的 比如飞腾 比如麒麟(银河麒麟 还有华为的麒麟 980) ...

  3. Java最新学习线路(基础,源码,项目,实战)

    如需获取以下学习资源请关注公众号:Java编程指南 我们为自学者编程的或初学java的小伙伴们准备了一整套完整的学习资源和文章,还有我自己在自学路上的一些总结和学习线路,希望能帮到小伙伴们,如果有什么 ...

  4. Java基础(入门Java)

    今天是学习Java的第一天,为了保证在暑假里持续高效的学习,决定每周写一篇博客汇报总结当周进度,以此来督促自己不断的向更深更远的方向迈进.Java刚刚入门,看到的人若觉得某些地方不妥欢迎进行批评指导, ...

  5. luogu 黑题 P3724大佬

    #include<bits/stdc++.h> using namespace std; #define ll long long #define RG register #define ...

  6. 树型DP入门

    题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚 ...

  7. sql 占位符及部分时间函数

    Mysql 预处理占位符 %s -- 表示字段串 %d -- 表示整形数字 %f -- 表示浮点数 (UNIX_TIMESTAMP(DATE_SUB(now(), INTERVAL jp_days D ...

  8. nginx的代理服务

    nginx的代理服务 正向代理和反向代理 正向代理服务器就是用来让局域网的客户端接入外网访问外网资源,反向代理就是让外网的客户端接入局域网中的站点以访问点中的资源 正向代理 我是一个用户,我访问不了某 ...

  9. 012-zabbix主动模式

    6.1 主动模式 zabbix agent检测分为主动(agent active)和被动(agent)两种形式,主动与被动的说法均是相对于agent来讨论的.简单说明一下主动与被动的区别如下: 主动: ...

  10. java高并发核心要点|系列4|CPU内存指令重排序(Memory Reordering)

    今天,我们来学习另一个重要的概念. CPU内存指令重排序(Memory Reordering) 什么叫重排序? 重排序的背景 我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多.当CP ...