zoukankan      html  css  js  c++  java
  • Luogu4725 【模板】多项式对数函数(NTT+多项式求逆)

      https://www.cnblogs.com/HocRiser/p/8207295.html 安利!

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define P 998244353
    #define N 550000
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,a[N],r[N],b[N],c[N],A[N],t;
    int ksm(int a,int k)
    {
    	int s=1;
    	for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
    	return s;
    }
    int inv(int a){return ksm(a,P-2);}
    void DFT(int n,int *a,int g)
    {
    	for (int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|(i&1)*(n>>1);
    	for (int i=0;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
    	for (int i=2;i<=n;i<<=1)
    	{
    		int wn=ksm(g,(P-1)/i);
    		for (int j=0;j<n;j+=i)
    		{
    			int w=1;
    			for (int k=j;k<j+(i>>1);k++,w=1ll*w*wn%P)
    			{
    				int x=a[k],y=1ll*w*a[k+(i>>1)]%P;
    				a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P;
    			}
    		}
    	}
    }
    void IDFT(int *a,int n)
    {
    	DFT(n,a,inv(3));
    	int u=inv(n);
    	for (int i=0;i<n;i++) a[i]=1ll*a[i]*u%P;
    }
    void mul(int *a,int *b,int n)
    {
    	DFT(n,a,3),DFT(n,b,3);
    	for (int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%P;
    	IDFT(a,n);
    }
    void Inv(int *a,int *b,int n) 
    {
    	if (n==1) {for (int i=0;i<t;i++) b[i]=0;b[0]=inv(a[0]);return;}
    	Inv(a,b,n>>1);
    	for (int i=0;i<n;i++) A[i]=a[i];
    	for (int i=n;i<(n<<1);i++) A[i]=0;
    	n<<=1;
    	DFT(n,A,3),DFT(n,b,3);
    	for (int i=0;i<n;i++) b[i]=1ll*b[i]*(P+2-1ll*A[i]*b[i]%P)%P;
    	IDFT(b,n);
    	n>>=1;
    	for (int i=n;i<(n<<1);i++) b[i]=0;
    }
    void trans(int *a,int *b,int n){for (int i=0;i<n-1;i++) b[i]=1ll*a[i+1]*(i+1)%P;}
    void dx(int *a,int *b,int n){b[0]=0;for (int i=1;i<n;i++) b[i]=1ll*a[i-1]*inv(i)%P;}
    void Ln(int *a)
    {
    	trans(a,c,t);
    	Inv(a,b,t>>1);
    	mul(c,b,t);
    	dx(c,a,t);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("ln.in","r",stdin);
    	freopen("ln.out","w",stdout);
    	const char LL[]="%I64d
    ";
    #else
    	const char LL[]="%lld
    ";
    #endif
    	n=read();
    	for (int i=0;i<n;i++) a[i]=read();
    	t=1;while (t<=(n<<1)) t<<=1;
    	Ln(a);
    	for (int i=0;i<n;i++) printf("%d ",a[i]);
    	return 0;
    }
    //ln(F(x))=G(x)
    //ln(F(x))'=G(x)'
    //F(x)'/F(x)=G(x)'
    //G(x)=dx(F(x)'/F(x))
    

      

  • 相关阅读:
    HDU 4539郑厂长系列故事――排兵布阵(状压DP)
    HDU 2196Computer(树形DP)
    HDU 4284Travel(状压DP)
    HDU 1520Anniversary party(树型DP)
    HDU 3920Clear All of Them I(状压DP)
    HDU 3853LOOPS(简单概率DP)
    UVA 11983 Weird Advertisement(线段树求矩形并的面积)
    POJ 2886Who Gets the Most Candies?(线段树)
    POJ 2828Buy Tickets
    HDU 1394Minimum Inversion Number(线段树)
  • 原文地址:https://www.cnblogs.com/Gloid/p/10386553.html
Copyright © 2011-2022 走看看