zoukankan      html  css  js  c++  java
  • 【数学】多项式求逆

    多项式求逆

    https://www.luogu.com.cn/problem/P4238

    原理

    利用倍增来得到答案。

    假设现在已经得到 \(H(x)\),使得 \(F(x)H(x)\equiv 1 \pmod{x^{\lceil \frac{n}{2} \rceil}}\)

    同时有 \(F(x)G(x)\equiv 1 \pmod{x^{\lceil \frac{n}{2} \rceil}}\)

    而且 \(F(x)\not\equiv 0 \pmod{x^{\lceil \frac{n}{2} \rceil}}\)

    因此 \(H(x)-G(X)\equiv 0 \pmod{x^{\lceil \frac{n}{2} \rceil}}\)

    同时我们也有 \(H(x)-G(X)\equiv 0 \pmod{x^{\lfloor\frac{n}{2} \rfloor}}\)

    进而有 \((H(x)-G(X))^2 \equiv 0 \pmod{x^n}\)

    因为 \(\lceil \frac{n}{2} \rceil + \lfloor\frac{n}{2} \rfloor = n\)

    展开得到 \(H^2(X) -2H(X)G(X) + G^2(X) \equiv 0 \pmod{x^n}\)

    两边同乘 \(F(X)\),可得 \(H^2(X)F(X) -2H(X) + G(X) \equiv 0 \pmod{x^n}\)

    因此 \(2H(X) - H^2(X)F(X) \equiv G(X) \pmod{x^n}\)

    实现

    // Problem: P4238 【模板】多项式乘法逆
    // Contest: Luogu
    // URL: https://www.luogu.com.cn/problem/P4238
    // Memory Limit: 125 MB
    // Time Limit: 1000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    #include<bits/stdc++.h>
    using namespace std;
    
    #define debug(x) cerr << #x << ": " << (x) << endl
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    
    using pii = pair<int, int>;
    using ll = long long;
    
    #define int long long
    
    inline void read(int &x){
        int s=0; x=1;
        char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    const int N=3e5+5, rt=3, mod=998244353;
    
    int rev[N], tot=1, bit;
    
    ll fpow(ll x, int p, ll mod){
    	int res=1;
    	for(; p; p>>=1, x=x*x%mod) if(p&1) res=res*x%mod;
    	return res;
    }
    
    ll inv(ll x, ll mod){
    	return fpow(x, mod-2, mod);
    }
    
    ll mul(ll x, int p, ll mod){
    	ll res=0;
    	for(; p; p>>=1, x=(x+x)%mod) if(p&1) res=(res+x)%mod;
    	return res;
    }
    
    void NTT(ll *a, int type, int mod){
    	for(int i=0; i<tot; i++){
    		a[i]%=mod;
    		if(i<rev[i]) swap(a[i], a[rev[i]]);
    	}
    	
    	for(int mid=1; mid<tot; mid<<=1){
    		ll w1=fpow(rt, (type==1? (mod-1)/(mid<<1): mod-1-(mod-1)/(mid<<1)), mod);
    		for(int i=0; i<tot; i+=mid*2){
    			ll wk=1;
    			for(int j=0; j<mid; j++, wk=wk*w1%mod){
    				auto x=a[i+j], y=wk*a[i+j+mid]%mod;
    				a[i+j]=(x+y)%mod, a[i+j+mid]=(x-y+mod)%mod;
    			}
    		}
    	}
    	
    	if(type==-1){
    		for(int i=0; i<tot; i++) a[i]=a[i]*inv(tot, mod)%mod;
    	}
    }
    
    int n;
    int A[N], B[N], C[N];
    
    void poly_inv(int sz, int *a, int *b){
    	if(sz==1) return b[0]=inv(a[0], mod), void();
    	poly_inv(sz+1>>1, a, b);
    	
    	// init
    	bit=0, tot=1;
    	while(tot<=(sz-1<<1)) tot<<=1, bit++;
    	for(int i=0; i<tot; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
    	
    	rep(i,0,sz-1) C[i]=a[i];
    	rep(i,sz,tot-1) C[i]=0;
    	
    	NTT(C, 1, mod), NTT(b, 1, mod);
    	rep(i,0,tot-1) b[i]=(2-C[i]*b[i]%mod+mod)%mod*b[i]%mod;
    	NTT(b, -1, mod);
    	
    	rep(i,sz,tot-1) b[i]=0;
    }
    
    signed main(){
    	cin>>n;
    	rep(i,0,n-1) read(A[i]);
    	poly_inv(n, A, B);
    	rep(i,0,n-1) cout<<B[i]<<' ';
    	cout<<endl;
    	
    	return 0;
    }
    
  • 相关阅读:
    6.1(续)索引、索引组织表--Oracle模式对象
    Docker容器中用户权限管理
    setfacl、getfacl
    Premiere常见配置优化
    SSH代理
    给U盘分区
    IO模型
    window 系统各个版本 ie浏览器 默认版本 bootstrap ie版本兼容
    代码多版本处理及自动化打包部署流程
    vue3 watch 监听数组 对象
  • 原文地址:https://www.cnblogs.com/Tenshi/p/15667830.html
Copyright © 2011-2022 走看看