• 【数学】多项式取 ln


    多项式取 ln

    模板题传送门

    给你 \(A\),让你求 \(B(x) \equiv lnA(x) \pmod {x^n}\)

    两遍求导,得到 \(B'(x) \equiv \frac{A'(x)}{A(x)} \pmod {x^n}\)

    然后积分即有 \(B(x) \equiv \int\frac{A'(x)}{A(x)}dx \pmod {x^n}\)

    #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;
    }
    
    void poly_der(int sz, int *a, int *b){
    	rep(i,1,sz-1) b[i-1]=i*a[i]%mod;
    	b[sz-1]=0;
    }
    
    void poly_int(int sz, int *a, int *b){
    	rep(i,1,sz-1) b[i]=a[i-1]*inv(i, mod)%mod;
    	b[0]=0; 
    }
    
    int inv_A[N], der_A[N];
    
    void conv(int *a, int *b){
    	NTT(a, 1, mod), NTT(b, 1, mod);
    	rep(i,0,tot-1) a[i]=a[i]*b[i]%mod;
    	NTT(a, -1, mod);
    }
    
    void poly_ln(int sz, int *a, int *b){
    	poly_inv(sz, a, inv_A);
    	poly_der(sz, a, der_A);
    	
    	// init
    	bit=0, tot=1;
    	while(tot<=sz-1+sz-2) tot<<=1, bit++;
    	for(int i=0; i<tot; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
    
    	conv(inv_A, der_A);
    	
    	poly_int(sz, inv_A, b);
    }
    
    signed main(){
    	cin>>n;
    	rep(i,0,n-1) read(A[i]);
    	poly_ln(n, A, B);
    	rep(i,0,n-1) cout<<B[i]<<' ';
    	cout<<endl;
    	
    	return 0;
    }
    
  • 相关阅读:
    ASP.NET 错误
    linux下使用蓝牙设备【转】
    AIDL Android中的远程接口 [转]
    Handler理解
    Hid Report Descriptor
    Android kernel x86 编译方法
    Android Init Language
    DBUS 资源
    Analysing Bluetooth Keyboard Traffic with hcidump
    DBUS基础知识
  • 原文地址:https://www.cnblogs.com/Tenshi/p/15668190.html
Copyright © 2020-2023  润新知