码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu P5850 calc加强版

时间:2020-05-28 21:42:16      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:link   else   tin   play   alc   c++   uil   main   out   

Link

\[ans_n=[x^n]\prod\limits_{i=1}^k(1+ix)=[x^n]\exp(\sum\limits_{i=1}^k\ln(1+ix))=[x^n]\exp(\sum\limits_{j\ge1}\frac{(-1)^{j+1}\sum\limits_{i=1}^ki^j}jx^j)\\sum\limits_{j\ge0}\sum\limits_{i=1}^k\frac{i^jx^j}{j!}=\sum\limits_{i=0}^k\exp(ix)=\frac{\exp((k+1)x)-1}{\exp(x)-1} \]

#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=1<<20|1,P=998244353;
int k,n,len,fac[N],inv[N],ifac[N],rev[N],w[N];
int getlen(int n){return 1<<(32-__builtin_clz(n));}
int inc(int a,int b){return a+=b-P,a+(a>>31&P);}
int dec(int a,int b){return a-=b,a+(a>>31&P);}
int mul(int a,int b){return 1ll*a*b%P;}
int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
void init(int n)
{
    int lim=1<<(len=32-__builtin_clz(n)),g=pow(3,(P-1)/lim);
    w[lim>>1]=1,fac[0]=ifac[0]=inv[0]=fac[1]=ifac[1]=inv[1]=1;
    for(int i=1;i<lim;++i) rev[i]=(rev[i>>1]>>1)|(i&1? lim>>1:0);
    for(int i=(lim>>1)+1;i<lim;++i) w[i]=mul(w[i-1],g);
    for(int i=(lim>>1)-1;i;--i) w[i]=w[i<<1];
    for(int i=2;i<=lim;++i) fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[i-1],inv[i]=mul(inv[P%i],P-P/i));
}
void NTT(int*a,int lim,int f)
{
    if(!~f) std::reverse(a+1,a+lim);
    for(int i=0,x=len-__builtin_ctz(lim);i<lim;++i) if(i<rev[i]>>x) std::swap(a[i],a[rev[i]>>x]);
    for(int i=1;i<lim;i<<=1) for(int j=0,d=i<<1;j<lim;j+=d) for(int k=0,x;k<i;++k) x=mul(a[i+j+k],w[i+k]),a[i+j+k]=dec(a[j+k],x),a[j+k]=inc(a[j+k],x);
    if(!~f) for(int i=0,x=P-(P-1)/lim;i<lim;++i) a[i]=mul(a[i],x);
}
void Inv(int*a,int*b,int deg)
{
    if(deg==1) return b[0]=pow(a[0],P-2),void();
    static int t[N];int lim=getlen(deg*2-2);
    Inv(a,b,(deg+1)>>1),memcpy(t,a,deg<<2),memset(t+deg,0,(lim-deg)<<2),NTT(t,lim,1),NTT(b,lim,1);
    for(int i=0;i<lim;++i) b[i]=mul(dec(2,mul(b[i],t[i])),b[i]);
    NTT(b,lim,-1),memset(b+deg,0,(lim-deg)<<2);
}
void Der(int*a,int*b,int deg){for(int i=1;i<deg;++i)b[i-1]=mul(a[i],i);b[deg-1]=0;}
void Int(int*a,int*b,int deg){for(int i=1;i<deg;++i)b[i]=mul(a[i-1],inv[i]);b[0]=0;}
void Ln(int*a,int*b,int deg)
{
    static int t[N];int lim=getlen(deg*2-2);
    Inv(a,t,deg),Der(a,b,deg),NTT(t,lim,1),NTT(b,lim,1);
    for(int i=0;i<lim;++i) t[i]=mul(t[i],b[i]);
    NTT(t,lim,-1),Int(t,b,deg),memset(t,0,lim<<2),memset(b+deg,0,(lim-deg)<<2);
}
void Exp(int*a,int*b,int deg)
{
    if(deg==1) return b[0]=1,void();
    static int t[N];int lim=getlen(deg*2-2);
    Exp(a,b,(deg+1)>>1),Ln(b,t,deg);
    for(int i=0;i<deg;++i) t[i]=dec(a[i],t[i]);
    memset(t+deg,0,(lim-deg)<<2),++t[0],NTT(t,lim,1),NTT(b,lim,1);
    for(int i=0;i<lim;++i) b[i]=mul(b[i],t[i]);
    NTT(b,lim,-1),memset(b+deg,0,(lim-deg)<<2),memset(t+deg,0,(lim-deg)<<2);
}
void Get_Inv(int*a,int*b,int n)
{
    static int t[N];
    Inv(a,t,n),memcpy(b,t,4*n);
}
void Get_Exp(int*a,int*b,int n)
{
    static int t[N];
    Exp(a,t,n),memcpy(b,t,4*n);
}
int f[N],g[N];char obuf[1<<23],*oS=obuf;
void write(int x){if(!x)return;write(x/10),*oS++=48+x%10;}
void print(int x){if(!x)*oS++=‘0‘;else write(x);*oS++=‘\n‘;}
int main()
{
    scanf("%d%d",&k,&n),init(2*n);int lim=getlen(2*n);
    for(int i=0,pw=k;i<=n;++i) f[i]=mul(pw,ifac[i+1]),g[i]=i&1? P-ifac[i+1]:ifac[i+1],pw=mul(pw,k);
    Get_Inv(g,g,n+1),NTT(f,lim,1),NTT(g,lim,1);
    for(int i=0;i<lim;++i) g[i]=mul(f[i],g[i]);
    NTT(g,lim,-1),memset(f,0,4*lim);
    for(int i=1;i<=n;++i) f[i]=mul(fac[i-1],g[i]),~i&1? f[i]=dec(0,f[i]):0;
    Get_Exp(f,f,n+1);
    for(int i=1;i<=n;++i) print(mul(fac[i],f[i]));
    fwrite(obuf,1,oS-obuf,stdout);
}

Luogu P5850 calc加强版

标签:link   else   tin   play   alc   c++   uil   main   out   

原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12983773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!