孩子做了一早上最终 T 了求卡常
查看原帖
孩子做了一早上最终 T 了求卡常
691447
xcyyyyyy楼主2024/6/28 11:43
#include<bits/stdc++.h>
using namespace std;
#define p 998244353
#define L 1<<23
#define Poly basic_string<int>
int rev[L];int fac[L],pinv[L],inv[L],wn[L];
inline int qpow(int a,int b){int ans=1;for(;b;b>>=1,a=1ll*a*a%p)if(b&1)ans=1ll*ans*a%p;return ans;}
void ntt(Poly &a,int opt){
	int n=a.size();
	for(int i=1;i<n;i++)rev[i]=rev[i>>1]>>1,(i&1)&&(rev[i]|=n>>1);
	for(int i=0;i<n;i++)if(rev[i]>i)swap(a[i],a[rev[i]]);
	for(int l=2,m=1;l<=n;l<<=1,m<<=1){
		int Wn=qpow(opt==1?3:qpow(3,p-2),(p-1)/l);
        wn[0]=1;for(int j=1;j<m;j++)wn[j]=1ll*wn[j-1]*Wn%p;
		for(auto b=a.begin();b<a.end();b+=l>>1){
			for(int j=0;j<m;j++,b++){
				int t=1ll*b[m]*wn[j]%p;
				b[m]=(b[0]-t+p)%p;
				b[0]=(b[0]+t)%p;
			}
		}
	}
	if(opt==-1){for(int i=0;i<n;i++)a[i]=1ll*a[i]*inv[n]%p;}
}
Poly mul(Poly a,Poly b){
	int n=a.size(),len=n+n;
	a.resize(len);b.resize(len);ntt(a,1);ntt(b,1);
	for(int i=0;i<len;i++)a[i]=1ll*a[i]*b[i]%p;
	ntt(a,-1);a.resize(n);
	return a;
}
Poly exmul(Poly a,Poly b){
	int n=a.size()+b.size()-1,len=1<<__lg(n-1)+1;
	a.resize(len),b.resize(len);ntt(a,1);ntt(b,1);
	for(int i=0;i<len;i++)a[i]=1ll*a[i]*b[i]%p;
	ntt(a,-1);a.resize(n);
	return a;
}
Poly mul(Poly a,int k){for(int i=0;i<a.size();i++)a[i]=1ll*a[i]*k%p;return a;}
Poly Sub(Poly a,const Poly &b){for(int i=0;i<a.size();i++)a[i]=(a[i]-b[i]+p)%p;return a;}
Poly Plus(Poly a,const Poly &b){for(int i=0;i<a.size();i++)a[i]=(a[i]+b[i])%p;return a;}
Poly Inv(const Poly &a){
	Poly f,g;
	int n=a.size();
	f+=qpow(a[0],p-2);
	for(int l=2;l<=n;l<<=1){
		f.resize(l);
		g.assign(a.begin(),a.begin()+l);
        mul(f,f);
		f=Sub(mul(f,2),mul(mul(f,f),g));
	}
	return f;
}
Poly Sqrt(const Poly &a){
    int n=a.size();
    Poly f,g;f+=1;
    for(int l=2;l<=n;l<<=1){
        f.resize(l);
        g.assign(a.begin(),a.begin()+l);
        f=mul(Inv(mul(f,2)),Plus(mul(f,f),g));
    }
    return f;
}
Poly Der(Poly a){for(int i=0;i+1<a.size();i++)a[i]=1ll*a[i+1]*(i+1)%p;a.back()=0;return a;}
Poly Int(Poly a){for(int i=a.size()-1;i;i--)a[i]=1ll*a[i-1]*inv[i]%p;a[0]=0;return a;}
Poly Ln(const Poly &a){
    return Int(mul(Der(a),Inv(a)));
}
Poly Exp(const Poly &a){
	Poly f,g;
	int n=a.size();
	f+=1;
	for(int l=2;l<=n;l<<=1){
		f.resize(l);
		g.assign(a.begin(),a.begin()+l);
		g=Sub(g,Ln(f));g[0]+=1;
		f=mul(f,g);
	}
	return f;
}
Poly Pow(const Poly &a,int k){
	if(!a[0]){
		Poly b,c;b.resize(a.size());c.resize(a.size());
		for(int x=0;x<a.size();x++)if(a[x]){
			for(int i=0;i+x<a.size();i++)b[i]=a[i+x];
			b=Pow(b,k);
			for(int i=0;i<a.size();i++)c[i]=i>=1ll*x*k?b[i-x*k]:0;
			return c;
		}
		return b;
	}
	else{
		Poly b=a;
		int inv=qpow(a[0],p-2),pw=qpow(a[0],k);
		for(int i=0;i<b.size();i++)b[i]=1ll*b[i]*inv%p;
        Poly c=mul(Ln(b),k);
		b=Exp(mul(Ln(b),k));
		for(int i=0;i<b.size();i++)b[i]=1ll*b[i]*pw%p;
		return b;
	}
}
void Polyinit(){
	inv[0]=inv[1]=fac[0]=fac[1]=pinv[0]=pinv[1]=1;
	for(int i=2;i<L;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p,fac[i]=1ll*fac[i-1]*i%p,pinv[i]=1ll*pinv[i-1]*inv[i]%p;
}
#define N 200005
int n,m,k,a[N<<1],len;
Poly D,Q,f[N];
Poly calc(int l,int r){
    if(l==r)return f[l];
    int mid=(l+r)>>1;
    return exmul(calc(l,mid),calc(mid+1,r));
}
int main(){
    Polyinit();
    scanf("%d%d",&n,&k);
    for(int i=1,x;i<=n;i++)scanf("%d",&x),a[x]=1;
    int mx=0;
    for(int l=1,r=1;l<=2*n;l=++r){
        if(a[l]!=1)continue;
        while(r<2*n&&a[r+1]==1)++r;
        mx=max(mx,r-l+1);
    }
    len=1<<__lg(mx+2)+1;
    for(int l=2;l<=len;l<<=1){
        D.resize(l);
        Pow(D,k);
        Poly b=mul(Pow(D,k),(-k-1+p)%p);
        ++b[0];++b[1];b=Inv(b);
        Poly a=D;
        for(int i=(l>>1)-1;i>=0;i--)a[i+1]=(a[i+1]+a[i])%p;
        a=Sub(a,Pow(D,k+1));a[1]=(a[1]-1)%p;
        D=Sub(D,mul(a,b));
    }
    Q.resize(len);Q[0]=1;
    for(int i=0;i+1<D.size();i++)D[i]=D[i+1];D.back()=0;
    Q=mul(Q,Inv(D));
    for(int l=1,r=1;l<=2*n;l=++r){
        if(a[l]!=1)continue;
        while(r<2*n&&a[r+1]==1)++r;
        int n=r-l+1;++m;len=1<<__lg(n+1)+1;
        Poly t;t.resize(len);
        for(int i=0;i<len;i++)t[i]=Q[i];
        t=Pow(t,n+1);
        f[m].resize(n+1);
        for(int i=0;i<=n;i++)f[m][i]=1ll*t[i]*(n-i+1)%p*inv[n+1]%p;
    }
    Poly g=calc(1,m);int ans=0;
    for(int i=0;i<n;i++)
        ans=(ans+1ll*g[i]*n%p*inv[n-i]%p*qpow(1ll*fac[n]*pinv[n-i]%p*pinv[i]%p,p-2)%p)%p;
    printf("%d",ans);
}

2024/6/28 11:43
加载中...