首页 > 其他分享 >多项式初步

多项式初步

时间:2024-02-23 22:23:22浏览次数:40  
标签:cp frac int 多项式 初步 mod equiv

多项式初步

目录

自己写的

分治FFT/NTT Part1

给定序列 \(g_{1\dots n - 1}\),求序列 \(f_{0\dots n - 1}\)。

其中 \(f_i=\sum_{j=1}^if_{i-j}g_j\),边界为 \(f_0=1\)。

可以考虑cdq分治,对于f数组f[1,3|0,0]

假设左半边已经处理完,如何处理算左边对右边的贡献呢

提出[1,3,0,0](注意后面要清零),乘上g数组

然后把结果的后半加到f中

分治FFT/NTT Part2

求\(\prod (1+x^{c_i}),\sum c_i=n\)

①.多项式求逆:

问题:

已知一个次数为\(n-1\)的多项式\(F(x)\),求一个多项式\(G(x)\)使得\(F(x)*G(x)\equiv 1\)(\(mod x^{n}\)),所有运算在模998244353意义下进行

怎么搞?

先进行一点分析:

如果\(F(x)\)只有一项,那么\(G(x)\)里也只有一项,就是\(F(x)\)里那项的逆元

那么如果我们已知一个多项式\(H(x)\)满足\(F(x)*H(x)\equiv 1\)(\(mod\) \(x^{\frac{n}{2}}\))

很显然,根据要求,同时有:\(F(x)*G(x)\equiv 1\)(\(mod\) \(x^{\frac{n}{2}}\))

下式减上式,得到:

\(F(x)(G(x)-H(x))\equiv 0\)(\(mod\) \(x^{\frac{n}{2}}\))

于是有

\(G(x)-H(x)\equiv 0\)(\(mod\) \(x^{\frac{n}{2}}\))

两边平方,可以得到:

\((G(x)-H(x))^{2}\equiv 0\) (\(mod\) \(x^{n}\))

展开,得:

\(G(x)^{2}+H(x)^{2}-2G(x)H(x)\equiv 0\)(\(mod\) \(x^{n}\))

两边乘一个\(F(x)\),有:

\(F(x)G(x)^{2}+F(x)H(x)^{2}-2F(x)G(x)H(x)\equiv 0\)(\(mod\) \(x^{n}\))

根据要求,\(F(x)G(x)\equiv 1\)(\(mod\) \(x^{n}\))

于是上式可以化简成:

\(G(x)+F(x)H(x)^{2}-2H(x)\equiv 0\)(\(mod\) \(x^{n}\))

移项,得到:

\(G(x)\equiv 2H(x)-F(x)H(x)^{2}\) (\(mod\) \(x^{n}\))

这样就可以倍增求解了

②.多项式带余除法:

多项式求逆是多项式除法的基础,如果你不会多项式求逆,请看这里

问题:已知两个多项式\(F(x)\)(次数为n),\(G(x)\)(次数为m),求两个多项式\(Q(x)\)与\(R(x)\),满足\(F(x)=G(x)Q(x)+R(x)\),所有运算在模998244353意义下进行

推一发式子:

\(F(x)=G(x)Q(x)+R(x)\)

用\(\frac{1}{x}\)替代\(x\),得到:

\(F(\frac{1}{x})=G(\frac{1}{x})Q(\frac{1}{x})+R(\frac{1}{x})\)

两边乘一个\(x^{n}\),得:

\(x^{n}F(\frac{1}{x})=x^{m}G(\frac{1}{x})x^{n-m}Q(\frac{1}{x})+x^{n}R(\frac{1}{x})\)

对表达式\(F(x)=G(x)Q(x)+R(x)\)进行分析,可以看到,若\(F(x)\)次数为n,\(G(x)\)次数为m,则\(Q(x)\)次数为\(n-m\),\(R(x)\)次数不超过m-1

那么对自变量先取逆再乘一个最高次数等价于构造一个系数与原多项式恰好相反的多项式!

也即若\(F(x)=\sum_{i=0}^{n}a_{i}x^{i}\),则\(x^{n}F(\frac{1}{x})=\sum_{i=0}^{n}a_{n-i}x^{i}\)

我们记\(x^{n}F(\frac{1}{x})=\sum_{i=0}^{n}a_{n-i}x^{i}=F^{T}(x)\)

那么上式可以简写成\(F^{T}(x)=G^{T}(x)Q^{T}(x)+R^{T}(x)\)

可以发现,\(R^{T}(x)\)这个多项式前\((n-m+1)\)项的系数均为0!

因此如果我们在\(mod\) \(x^{n-m+1}\)意义下,可以立刻得出这个等式:

\(F^{T}(x)\equiv G^{T}(x)Q^{T}(x)\)(\(mod\) \(x^{n-m+1}\))

那么移项即得:

\(Q^{T}(x)\equiv \frac{F^{T}(x)}{G^{T}(x)}\)(\(mod\) \(x^{n-m+1}\))

这样就求出了\(Q(x)\),然后基于原表达式,可得:

\(R(x)=F(x)-G(x)Q(x)\)

\(R(x)\)就算出来了

③.多项式开根:

问题:已知一个多项式\(F(x)\)次数为\(n-1\),求一个多项式\(G(x)\)使得\((G(x))^{2}\equiv F(x)\)(\(mod\) \(x^{n}\))

(保证常数项为\(1\))

仍然是推式子

首先,不难发现的是如果\(F(x)\)次数为0,那么\(G(x)=1\)

类似多项式求逆,我们倍增处理:

设已知\(H(x)^{2}\equiv F(x)\)(\(mod\) \(x^{\frac{n}{2}}\))

那么有\(H(x)^{2}-F(x)\equiv 0\)(\(mod\) \(x^{\frac{n}{2}}\))

两边平方,得:

\([H(x)^{2}-F(x)]^{2}\equiv 0\)(\(mod\) \(x^{n}\))

两边加上\(4H(x)^{2}F(x)\),得到:

\([H(x)^{2}+F(x)]^{2}\equiv 4H(x)^{2}F(x)\)(\(mod\) \(x^{n}\))

两边除掉\(4H(x)^{2}\),得:

\(\frac{[H(x)^{2}-F(x)]^{2}}{4H(x)^{2}}\equiv F(x)\)(\(mod\) \(x^{n}\))

可以发现左边是一个完全平方的形式,那么我们整理一下,得到:

\([\frac{H(x)^{2}-F(x)}{2H(x)}]^{2}\equiv F(x)\)(\(mod\) \(x^{n}\))

那么我们所求的\(G(x)\)不就出来了嘛

\(G(x)=\frac{H(x)^{2}-F(x)}{2H(x)}\)

用类似多项式求逆的方法递归求解即可

④.多项式对数:

问题:已知一个次数为\(n-1\)的多项式\(F(x)\),求一个多项式\(G(x)\)使得\(G(x)\equiv ln(F(x))\)(\(mod\) \(x^{n}\))

(保证\(F(x)\)常数项为1)

这个比较简单:

两边求导,得:

\(G^{'}(x)\equiv \frac{F^{'}(x)}{F(x)}\)(\(mod\) \(x^{n}\))

右侧都已知,直接多项式求逆计算出来即可

然后两边做不定积分,本来会有一个常数项,但是考虑到\(ln(F(0))=ln1=0=C\),因此常数项直接为0即可

⑤.多项式exp:

问题:已知一个多项式\(F(x)\)次数为\(n-1\),求一个多项式\(G(x)\)满足\(G(x)\equiv e^{F(x)}\)(\(mod\) \(x^{n}\))

保证\(F(x)\)常数项为\(0\)

好像有点困难...

首先有一个基础知识:

我们可以用牛顿迭代求出一个多项式的多项式零点

也即已知一个多项式\(F(x)\),可以利用牛顿迭代求出一个多项式\(G(x)\)满足\(F(G(x))\equiv 0\)(\(mod\) \(x^{n}\))

为什么我们要知道这件事情?

假设我们已知了\(G_{0}(x)\equiv e^{F(x)}\)(\(mod\) \(x^{\frac{n}{2}}\)

那么我们需要求出的就是\(G_{0}\)与\(G(x)\)的关系

首先,根据牛顿迭代公式,可得:
\(G(x)=G_{0}(x)-\frac{F(G_{0}(x)}{F^{'}(G_{0}(x))}\)

(关于这个公式的来历,我在最下面有一个感性理解的部分)

但是这个嵌套的东西还是很闹心

那么我们从另一个方向再进行一些推导:

已知\(G(x)\equiv e^{F(x)}\)(\(mod\) \(x^{n}\))

那么两边取对数

\(lnG(x)-F(x)\equiv 0\)(\(mod\) \(x^{n}\))

设\(H(G(x))\equiv lnA(x)-B(x)\equiv 0\) (\(mod\) \(x^{n}\))

那么求导即得到\(H^{'}(G_{0}(x))\equiv G_{0}^{-1}(x)\)

那么再回到上面的表达式:

\(G(x)=G_{0}(x)-\frac{H(G_{0}(x)}{H^{'}(G_{0}(x))}\)

最后整理一遍,得到:

\(G(x)\equiv G_{0}(x)[1-lnG_{0}(x)+F(x)]\)(\(mod\) \(x^{n}\))

这样就可以倍增去求了

关于牛顿迭代:

假设我们要求一个函数\(f(x)\)的零点,那么我们不妨假设这个零点是\(x_{0}\),然后将\(f(x)\)在\(x=x_{0}\)处求导得\(f^{'}(x_{0})\),计算出在这一点的切线

\(y=f^{'}(x_{0})(x-x_{0})+f(x_{0})\)

接下来求出该切线与\(x\)轴交点横坐标\(x_{1}\),那么\(x_{1}\)的精度就比\(x_{0}\)的精度好一倍(大概是这个意思吧)

我们计算出\(x_{1}\)的表达式,可以发现\(x_{1}=x_{0}-\frac{f(x_{0})}{f^{'}(x_{0})}\),那么这就是一个递推关系式,将未知数\(x\)换为多项式\(G(x)\)即得回上式

⑥.多项式快速幂:

问题:已知一个次数为\(n-1\)的多项式\(F(x)\),求一个多项式\(G(x)\)满足\(G(x)\equiv F(x)^{k}\)

这个...你需要多项式exp

直接推一发式子就可以了:

\(G(x)\equiv F(x)^{k}\)

\(G(x)\equiv e^{lnF(x)^{k}}\)

\(G(x)\equiv e^{klnF(x)}\)

这样写个多项式ln和多项式exp就可以了

模板

基础操作

#include<bits/stdc++.h>
#define Fu(i,a,b) for(register int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define mod 998244353 
using namespace std;
int ksm(int a,int k){
	int ans=1;
	while(k){
		if(k&1) ans=1ll*ans*a%mod;
		a=1ll*a*a%mod,k>>=1;
	}return ans;
}
const int N=4*1e5+5;
int rev[N],g=3,gi=ksm(3,mod-2);
void ntt(int n,int *a,int inv){
	Fu(i,0,n) if(i<rev[i]) swap(a[i],a[rev[i]]);
	for(int len=1;len<n;len<<=1){
		int wn=ksm(inv?g:gi,(mod-1)/(len<<1));
		for(int i=0;i<n;i+=len<<1){
			int w0=1;
			Fu(j,0,len-1){
				int x=a[i+j],y=1ll*w0*a[i+j+len]%mod;
				a[i+j]=(x+y)%mod,a[i+j+len]=(x-y+mod)%mod,w0=1ll*w0*wn%mod;
			}
		}
	}
}
int c[N];
void mul(int *a,int *b,int n){
	int len=1,bit=0;
	while(len<2*n) len<<=1,bit++;
	Fu(i,0,len) rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1),c[i]=i<n?b[i]:0;
	ntt(len,a,1),ntt(len,c,1);
	Fu(i,0,len) a[i]=1ll*a[i]*c[i]%mod;
	ntt(len,a,0);
	Fu(i,0,len) a[i]=i<n?1ll*a[i]*ksm(len,mod-2)%mod:0;
}
void inv(int *a,int *b,int n){
	if(n==1){
		a[0]=ksm(b[0],mod-2);
		return ;
	}inv(a,b,n+1>>1);
	int len=1,bit=0;
	while(len<2*n) len<<=1,bit++;
	Fu(i,0,len) rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1),c[i]=i<n?b[i]:0;
	ntt(len,a,1),ntt(len,c,1);
	Fu(i,0,len) a[i]=1ll*a[i]*(2ll-1ll*a[i]*c[i]%mod+mod)%mod;
	ntt(len,a,0);
	Fu(i,0,len) a[i]=i<n?1ll*a[i]*ksm(len,mod-2)%mod:0;
}
int inv2=ksm(2,mod-2),d[N];
void sqr(int *a,int *b,int n){
	if(n==1){
		a[0]=1;
		return ;
	}sqr(a,b,n+1>>1);
	Fu(i,0,n) d[i]=0;
	inv(d,a,n),mul(a,a,n);
	Fu(i,0,n) a[i]=1ll*inv2*(a[i]+b[i])%mod; 
	mul(a,d,n);
}
void ln(int *a,int *b,int n){
	memset(d,0,sizeof(d));
	inv(d,b,n);
	Fu(i,1,n-1) a[i-1]=1ll*b[i]*i%mod;
	a[n-1]=0;
	mul(a,d,n);
	Fd(i,n-1,1) a[i]=1ll*a[i-1]*ksm(i,mod-2)%mod;
	a[0]=0;
}
int e[N];
void exp(int *a,int *b,int n){
	if(n==1){
		a[0]=1;
		return ;
	}exp(a,b,n+1>>1); 
	ln(e,a,n);
	Fu(i,0,n-1) e[i]=(b[i]-e[i]+mod)%mod;
	e[0]++;
	mul(a,e,n);
}
int n,m,a[N],b[N];
int main(){
	return 0;
}

MTT

四次FFT版

#include<bits/stdc++.h>
#define Fu(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define lim 32000
using namespace std;
const long double pi=acos(-1.0);
struct cp{
	long double x,y;
	cp operator + (const cp& p){return (cp){x+p.x,y+p.y};}
	cp operator - (const cp& p){return (cp){x-p.x,y-p.y};}
	cp operator * (const cp& p){return (cp){x*p.x-y*p.y,x*p.y+y*p.x};}
}P1[400005],P2[400005],Q[400005];
int rev[400005];
long double ccos[400005],ssin[400005];
void fft(int n,cp *a,int inv){
	Fu(i,0,n) if(i<rev[i]) swap(a[i],a[rev[i]]);
	for(int mid=1;mid<n;mid<<=1){
		cp wn=(cp){ccos[mid],inv*ssin[mid]};
		for(int i=0;i<n;i+=mid<<1){
			cp w0=(cp){1,0};
			Fu(j,0,mid-1){
				cp x=a[i+j],y=w0*a[i+j+mid];
				a[i+j]=x+y,a[i+j+mid]=x-y,w0=w0*wn;
			}
		}
	}
}
void mul(int *ans,int *a,int *b,int n,int m,int p){
	Fu(i,0,n) P1[i]=(cp){a[i]/lim,a[i]%lim};
	Fu(i,0,m) Q[i]=(cp){b[i]/lim,b[i]%lim};
	int len=1,bit=0;
	while(len<=n+m+1) len<<=1,bit++,ccos[len]=cos(pi/len),ssin[len]=sin(pi/len);
	Fu(i,0,len) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
	fft(len,P1,1),fft(len,Q,1);
	Fu(i,0,len-1) P2[i]=P1[i?len-i:0],P2[i].y*=-1;
	Fu(i,0,len) Q[i].x/=len,Q[i].y/=len;
	Fu(i,0,len) P1[i]=P1[i]*Q[i],P2[i]=P2[i]*Q[i];
	fft(len,P1,-1),fft(len,P2,-1);
	Fu(i,0,n+m+1){
		long long a1b1,a1b2,a2b1,a2b2;
		a1b1=(long long)floor((P1[i].x+P2[i].x)/2+0.49)%p;
		a1b2=(long long)floor((P1[i].y+P2[i].y)/2+0.49)%p;
		a2b1=((long long)floor(P1[i].y+0.49)-a1b2)%p;
		a2b2=((long long)floor(P2[i].x+0.49)-a1b1)%p;
		ans[i]=((a1b1*lim+(a1b2+a2b1))*lim+a2b2)%p;
		ans[i]=(ans[i]+p)%p;
	}
} 
int n,m,p,a[100005],b[100005],ans[200005];
int main(){
	scanf("%d%d%d",&n,&m,&p);
	Fu(i,0,n) scanf("%d",&a[i]);
	Fu(i,0,m) scanf("%d",&b[i]);
	mul(ans,a,b,n,m,p);
	Fu(i,0,n+m) printf("%d ",ans[i]);
	return 0;
}

标签:cp,frac,int,多项式,初步,mod,equiv
From: https://www.cnblogs.com/zhy114514/p/18028185

相关文章

  • 数学:多项式
    拉格朗日插值快速傅里叶变换(FFT)已经不知道被这玩意劝退了多少次了。但理解之后其实不算很阴间的东西?前置知识多项式负数单位根快速傅里叶变换快速傅里叶逆变换快速数论变换(NTT/FNTT)前置知识FFT注意到FFT的运算到处都是又\(\cos\)又\(\sin\)的,有不小的精度问题......
  • 邮件地址校验测试点初步整理
    1、输入正确的邮箱格式2、输入的正确的邮箱地址中间包含空格3、输入的正确的邮箱地址前面有空格4、输入的正确的邮箱地址后面有空格5、不输入任何内容6、只输入空格7、输入纯英文、纯数字,英文+数字pass8、输入纯中文,纯符号,中文+符号9、输入超长字符10、输入以_开头或者结尾11、......
  • 最高法--就担保事项而言,执行董事签字的决议应初步认为与董事会决议具有同等效力
    (2021)最高法民申7872号  恩平市光谷光电科技有限公司、王良海等民间借贷纠纷民事申请再审审查民事裁定书申请人主张:(一)原判决认定光谷公司对王良海二审提交的证据无异议错误。光谷公司二审并未出具授权委托书,广东广伦律师事务所洪佳盛律师无权代理光谷公司就王良海二审提交的证......
  • 【多项式】任意模数 NTT/FTT
    现在有两个整数多项式\(A\),\(B\),\(0\lea_i,b_i\le10^9\),\(n\le10^5\),求它们的卷积,同时系数对\(p\le10^9\)取模。我们会发现,最终的系数可能会达到\(10^5\times10^9\times10^9=10^{23}\)级别,FFT会爆longdouble的精度;NTT,由于模数无特殊性质,完全不能使用。接......
  • 【多项式】【模版】FFT NTT
    多项式若\(A(x)=a_0+a_1x+a_2x^2+\dotsa_nx^n(a_n\ne0)\),则称\(A\)是\(n\)次多项式。初中概念,但在OI中可以玩出花来。多项式的表示方式像上面的介绍一样,用系数\(a_0,a_1,\dotsa_n\)来表示多项式的方法称为系数表示法。还有一种表示多项式的方法,就是对于\(n\)......
  • 【模板】多项式全家桶(多项式初等函数(部分))
    【模板】多项式初等函数同时作为https://github.com/caijianhong/template-poly的document。杂项数域为\(\mathbbF_{998244353}\),所以定义了mint为modint<998244353>。poly是多项式的类型,从std::vector<mint>继承而来。poly的构造函数如下:poly();explicitpoly(......
  • 多项式从入门到进门
    多项式全家福多项式一个以\(x\)为变量的多项式定义在一个代数域\(F\)上,将函数\(A(x)\)表示为形式和:\[A(x)=\sum\limits_{i=0}^{n-1}a_ix^i\]我们称\(a_0,a_1,\cdots,a_n\)为多项式的系数,所有系数都属于数域\(\mathbbF\)。如果一个多项式的最高次的非零系数是\(k......
  • slurm初步使用
    先使用脚本.sh1#!/bin/bash2#SBATCH--job-name=test3#SBATCH-pamd_2564#SBATCH--error=log/%J.err5#作业运行的标准错误输出将写到文件log/[JOBID].err文件中6#SBATCH--output=log/%J.out7#作业运行的标准输出将写到文件log/[JOBID].out文件中8......
  • python turtle库的初步认识
    pythonturtle库的初步认识一、设置主窗体的大小与位置.....turtle.setup(宽,高,与屏幕左侧的像素距离,与屏幕右侧的像素距离) #后两个数值为None时,该方向则默认居中二、画笔控制......turtle.penup() #抬起画笔,表示移动画笔不绘制形状turtle.pendown() #落下画笔,表示移......
  • P4512 【模板】多项式除法
    为什么不能直接用\(F(x)\timesG(x)^{-1}\)做?\(G(x)^{-1}\)是模\(x^{m+1}\)意义下的,\(n-m>m\)时得到的\(Q(x)\)就是错的。记\(F'(x)\)为\(F(x)\)系数翻转后的多项式,即若\(F(x)=\sum\limits_{i=0}^nf_ix^i\),则\(F'(x)=\sum\limits_{i=0}^nf_{n......