zoukankan      html  css  js  c++  java
  • 并不对劲的多项式求逆

    多项式求逆是一个很多人选择背诵全文的算法。

    #include<algorithm>
    #include<cmath>
    #include<complex>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
    #define maxlen 100010
    #define maxn (maxlen<<3)
    #define LL long long
    using namespace std;
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    void write(int x)
    {
    	if(x==0){putchar('0'),putchar('
    ');return;}
    	int f=0;char ch[20];
    	if(x<0)putchar('-'),x=-x;
    	while(x)ch[++f]=x%10+'0',x/=10;
    	while(f)putchar(ch[f--]);
    	putchar('
    ');
    	return;
    }
    const LL mod=998244353;
    int f[maxn],g[19][maxn],tmp[maxn],n,tmpn,len,nown,nowlen,r[maxn];
    int mul(int x,int y){int ans=1;while(y){if(y&1)ans=(LL)ans*(LL)x%mod;x=(LL)x*(LL)x%mod,y>>=1;}return ans;}
    void dnt(int * a,int f)
    {
    	rep(i,1,nown-1)if(i<r[i])swap(a[i],a[r[i]]);
    	for(int i=1;i<nown;i<<=1)
    	{
    		int wn=mul(3,(mod-1)/(i<<1)),x,y; 
    		if(f==-1)wn=mul(wn,mod-2);
    		for(int j=0;j<nown;j+=(i<<1))
    		{
    			int w=1;
    			rep(k,0,i-1)
    			{
    				x=a[j+k],y=(LL)w*(LL)a[j+i+k]%mod;
    				a[j+k]=((LL)x+(LL)y)%mod,a[j+k+i]=(((LL)x-(LL)y)%mod+(LL)mod)%mod;
    				w=(LL)w*(LL)wn%mod;
    			}
    		}
    	}
    	if(f==-1){int inv=mul(nown,mod-2);rep(i,0,nown-1)a[i]=(LL)a[i]*(LL)inv%mod;}
    }
    int main()
    {
    	n=read();
    	rep(i,0,n-1)f[i]=read()%mod;
    	g[0][0]=mul(f[0],mod-2);
    	for(len=0,tmpn=1;tmpn<n;len++,tmpn<<=1)
    	{
    		nown=tmpn<<1,nowlen=len+1;
    		rep(i,0,nown-1)tmp[i]=f[i];
    		nown=nown<<1,nowlen=nowlen+1;//一个nown次的多项式乘两个(nown/2)次的多项式,最高次为nown*2
    		rep(i,1,nown-1)r[i]=(r[i>>1]>>1)|((i&1)<<(nowlen-1));
    		rep(i,(tmpn<<1),nown-1)tmp[i]=0;
    		dnt(g[len],1),dnt(tmp,1);
    		rep(i,0,nown-1)g[len+1][i]=((2ll-(LL)tmp[i]*(LL)g[len][i])%mod+mod)*(LL)g[len][i]%mod;
    		dnt(g[len+1],-1);
    		rep(i,(tmpn<<1),nown-1)g[len+1][i]=0;
    	}
    	rep(i,0,n-1)printf("%d ",g[len][i]);
    	return 0;
    }
    

    多项式求逆指对于函数(F(x)),求(G(x)),使在每一项系数模(p)时,有(F(x)*G(x)equiv1(modspace x^n))
    考虑倍增求(G(x))
    (F(x)=f_0+f_1*x^1+..f_{n-1}*x^{n-1})(G(x)=g_0+g_1*x^1+..g_{n-1}*x^{n-1})
    (n=1)时,有 (F(x)*f_0^{-1}equiv1(modspace x^n))
    假设已经求出 (H(x)) 使 (F(x)*H(x)equiv1(modspace x^{lceilfrac{n}{2} ceil}))(1)
    (H(x)=h_0+h_1*x^1+..h_{n-1}*x^{n-1})
    因为 (F(x)*G(x)equiv1(modspace x^n))
    所以 (F(x)*G(x)equiv1(modspace x^{lceilfrac{n}{2} ceil}))(2)
    (2)-(1),得 (F(x)*(G(x)-H(x))equiv0(modspace x^{lceilfrac{n}{2} ceil}))
    两边同除 (F(x)) ,得 (G(x)-H(x)equiv0(modspace x^{lceilfrac{n}{2} ceil}))
    (forall iin [0,lceilfrac{n}{2} ceil),g_i-h_i=0)
    那么就有 ((G(x)-H(x))^2equiv0(modspace x^n))
    这是因为 ((G(x)-H(x))^2)(i(iin[0,n))) 项系数为 $$sum_{j=0}^{i}(g_j-h_j)*(g_{i-j}-h_{i-j})$$
    因为 (i<n),所以 (i-j,j) 中一定有一个小于 (lceilfrac{n}{2} ceil) ,即一定有一个为0,所以第 (i) 项系数为$$sum_{j=0}^{i}0=0$$证毕
    有这个结论就能得到 (G(x)^2-2*G(x)*H(x)+H^2(x)equiv0(modspace x^n))
    两边同乘 (F(x)),得 (F(x)*G(x)^2-2*F(x)*G(x)*H(x)+F(x)*H^2(x)equiv0(modspace x^n))
    (F(x)*G(x)equiv1(modspace x^n)),得 (G(x)-2*H(x)+F(x)*H^2(x)equiv0(modspace x^n))
    (G(x)equiv2*H(x)-F(x)*H^2(x)(modspace x^n))
    那么倍增+多项式乘法就可以进行多项式求逆了

  • 相关阅读:
    DNNClassifier 深度神经网络 分类器
    浏览器对MP4视频 帧宽度 高度的兼容性
    UnicodeEncodeError:'latin-1' codec can't encode character
    文件夹下 文件计数
    the largest value you actually can transmit between the client and server is determined by the amount of available memory and the size of the communications buffers.
    the “identity” of an object
    广告特征 用户特征
    如果一个维度全覆盖,则有效维度应该对该维度全覆盖
    a high-level neural networks AP
    使用 LDA 挖掘的用户喜好主题
  • 原文地址:https://www.cnblogs.com/xzyf/p/10031500.html
Copyright © 2011-2022 走看看