用了半年的exp,ln结果今天死了,求调
  • 板块学术版
  • 楼主zyxawa
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/1 22:19
  • 上次更新2024/7/2 08:03:22
查看原帖
用了半年的exp,ln结果今天死了,求调
673294
zyxawa楼主2024/7/1 22:19

是P7445的4 8 1这个数据查验出来的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> poly;
#define fix(f,n) f.resize(n+1)
int n,m,v,t,rev[2100001],w[2100001];
ll ans,a[100001],b[100001],pre[100001],inv[100001];
const int mod=998244353;
auto add=[](ll x,ll y){return x+y>=mod?x+y-mod:x+y;};
auto del=[](ll x,ll y){return x<y?x-y+mod:x-y;};
ll qpow(ll a,ll b){
    ll s=1;
    for(;b;b>>=1,a=a*a%mod) if(b&1) s=s*a%mod;
    return s;
}
void init(int n){
    pre[0]=inv[0]=w[n]=1,w[n|1]=qpow(3,(mod-1)/n);
    for(int i=2;i<n;i++) w[n|i]=1ll*w[n|i-1]*w[n|1]%mod;
    for(int i=n-1;i>=1;i--) w[i]=w[i<<1];
    for(int i=1;i<=100000;i++) pre[i]=pre[i-1]*i%mod,inv[i]=qpow(pre[i],mod-2);
}
void ntt(poly &f,int c,int n){
    fix(f,n-1);
    for(int i=0;i<n;i++) if(i<rev[i]) swap(f[i],f[rev[i]]);
    for(int k=1;k<n;k<<=1){
        for(int i=0;i<n;i+=k+k){
            for(int j=i,*p=w+k+k;j<i+k;j++){
                int x=f[j],y=f[j+k]*(*p++)%mod;
                f[j+k]=del(x,y);
                f[j]=add(x,y);
            }
        }
    }
    if(!c) reverse(f.begin()+1,f.begin()+n);
}
poly operator+(poly f,poly g){
    fix(f,max(f.size(),g.size())-1);
    for(int i=0;i<g.size();i++) f[i]=add(f[i],g[i]);
    return f;
}
poly operator-(poly f,poly g){
    fix(f,max(f.size(),g.size())-1);
    for(int i=0;i<g.size();i++) f[i]=del(f[i],g[i]);
    return f;
}
poly operator*(poly f,ll g){
    for(int i=0;i<f.size();i++) f[i]=f[i]*g%mod;
    return f;
}
poly operator*(poly f,poly g){
    int m=f.size()+g.size()-2,n=1<<__lg(m)+1,inv=0;
    for(int i=0;i<n;i++) rev[i]=(rev[i>>1]>>1)|(i&1?n>>1:0);
    ntt(f,1,n),ntt(g,1,n),inv=qpow(n,mod-2);
    for(int i=0;i<n;i++) f[i]=f[i]*g[i]%mod;
    ntt(f,0,n),fix(f,m);
    for(int i=0;i<=m;i++) f[i]=f[i]*inv%mod;
    return f;
}
poly Der(poly f){
    for(int i=1;i<f.size();i++) f[i-1]=f[i]*i%mod;
    return f.pop_back(),f;
}
poly Int(poly f){
    f.push_back(0);
    for(int i=f.size()-1;i>=1;i--) f[i]=f[i-1]*inv[i]%mod;
    return f[0]=0,f;
}
poly Inv(poly f){
    int n=f.size(),lst=f.size()-1,inv=0;
    poly g(1,qpow(f[0],mod-2));
    fix(f,n*2);
    for(int m=2;m/2<n;m<<=1){
        poly h(f.begin(),f.begin()+m);
        for(int i=0;i<m*2;i++) rev[i]=(rev[i>>1]>>1)|(i&1?m:0);
        ntt(g,1,m*2),ntt(h,1,m*2),inv=qpow(m*2,mod-2);
        for(int i=0;i<m*2;i++) g[i]=del(add(g[i],g[i]),g[i]*g[i]%mod*h[i]%mod);
        ntt(g,0,m*2),fix(g,m);
        for(int i=0;i<=m;i++) g[i]=g[i]*inv%mod;
    }
    return fix(g,lst),g;
}
poly Ln(poly f){
    poly g=Der(f)*Inv(f);
    return fix(g,(ll)f.size()-2),Int(g);
}
poly Exp(poly f){
    int n=f.size(),lst=f.size()-1;
    poly g(1,1);
    fix(f,n*2);
    for(int m=2;m/2<n;m<<=1){
        poly h(f.begin(),f.begin()+m);
        h[0]++,fix(g,m),g=g*(h-Ln(g));
    }
    return fix(g,lst),g;
}
poly Pow(poly f,int k){
    ll n=f.size()-1,b=0,val=0;
    while(b<=n&&!f[b]) b++;
    if(b*k>n||k>n&&!f[0]){
        for(int i=0;i<=n;i++) f[i]=0;
        return f;
    }
    for(int i=0;i<=n;i++) f[i]=(i+b<=n?f[i+b]:0);
    val=qpow(f[0],k);
    b*=k;
    f=Exp(Ln(f*qpow(f[0],mod-2))*k);
    for(int i=n;i>=b;i--) f[i]=f[i-b]*val%mod;
    for(int i=0;i<b;i++) f[i]=0;
    return f;
}
void build(ll l,ll r){
    if(l==r) return;
    ll mid=(l+r)/2,p=l*(n-r+1)%mod*qpow((ll)n*(n+1)/2%mod,mod-2)%mod;
    a[++t]=p*qpow(1-p+mod,mod-2)%mod,b[t]=qpow(1-p+mod,m);
    build(l,mid),build(mid+1,r);
}
poly calc1(int n){
    poly h(1,0);
    for(int m=2;m/2<n;m<<=1){
        fix(h,m);
        poly f=Pow(h,v),g=Pow(h,v-1)*v,w=h*h;
        for(int i=m;i>=1;i--) f[i]=f[i-1],g[i]=g[i-1];
        f[0]=g[0]=0,fix(w,m),f=f-w+h,g=g-h*2,f[1]=del(f[1],1),g[0]=add(g[0],1);
        h=h-f*Inv(g);
    }
    return fix(h,n),h;
}
pair<poly,poly> calc2(int l,int r){
    poly u,v;
    if(l==r) u.push_back(b[l]),v.push_back(1),v.push_back(mod-a[l]);
    else{
        int mid=(l+r)/2;
        auto [u0,v0]=calc2(l,mid);
        auto [u1,v1]=calc2(mid+1,r);
        u=u0*v1+u1*v0,v=v0*v1;
    }
    return {u,v};
}
int main(){
    init(1<<20);
    scanf("%d%d%d",&n,&m,&v),v+=2;
    if(n==1) return printf("0"),0;
    build(1,n);
    poly f=calc1(m+2),g=f;
    for(int i=1;i<=m+2;i++) g[i-1]=g[i];
    g[m+2]=0,f=Der(f)*Inv(g),fix(f,m);
    auto [u,k]=calc2(1,t);
    fix(u,m),fix(k,m),u=u*Inv(k);
    for(int i=0;i<=m;i++) (ans+=u[i]*pre[m]%mod*inv[i]%mod*inv[m-i]%mod*(qpow(v,i)-f[i]+mod)%mod*qpow(qpow(v,i),mod-2))%=mod;
    printf("%lld",ans);
    return 0;
}
2024/7/1 22:19
加载中...