1 条题解

  • 0
    @ 2025-10-22 17:51:41

    题解

    题目分析

    这是一道算法题目,需要根据具体题目要求进行求解。

    解题思路

    1. 问题分析

    • 仔细阅读题目描述,理解题目要求
    • 分析输入输出格式和约束条件
    • 确定需要使用的算法和数据结构

    2. 算法选择

    • 根据题目特点选择合适的算法
    • 考虑时间复杂度和空间复杂度
    • 确保算法能正确处理所有测试用例

    3. 实现要点

    • 注意边界条件的处理
    • 优化输入输出以提高效率
    • 确保代码的正确性和鲁棒性

    4. 调试和优化

    • 使用测试用例验证算法正确性
    • 分析性能瓶颈并进行优化
    • 确保代码能通过所有测试点

    注意事项

    • 仔细处理数据类型和精度问题
    • 注意数组越界和空指针问题
    • 确保算法的时间复杂度符合要求
    #include<bits/stdc++.h>
    #define ull unsigned long long
    using namespace std;
    const int N=65540,mod=998244353,g=3,invg=(mod+1)/3,inv2=(mod+1)/2;
    int rev[N],fac[N],ifac[N],p[N];
    ull a[N],b[N],c[N],*d[N<<2],x[N],y[N],w[N],inv[N];
    int qpow(int a,int b){
    	int ans=1;
    	while(b){
    		if(b&1){
    			ans=1ll*ans*a%mod;
    		}
    		a=1ll*a*a%mod;
    		b>>=1;
    	}
    	return ans;
    }
    void CLR(ull *a,int n){
    	for(int i=0;i<=n-1;i++){
    		a[i]=0;
    	}
    }
    void CPY(ull *a,ull *b,int n){
    	for(int i=0;i<=n-1;i++){
    		a[i]=b[i];
    	}
    }
    void INIT(int lim){
    	for(int i=0;i<lim;i++){
    		rev[i]=(rev[i>>1]>>1)|((i&1)?lim>>1:0);
    	}
    }
    void REV(ull *a,int n){
    	reverse(a,a+n);
    }
    void ADD(ull *a,ull *b,int n){
    	for(int i=0;i<=n-1;i++){
    		a[i]=(a[i]+b[i])%mod;
    	}
    }
    void DEC(ull *a,ull *b,int n){
    	for(int i=0;i<=n-1;i++){
    		a[i]=(a[i]-b[i]+mod)%mod;
    	}
    }
    void DRV(ull *a,int n){
    	for(int i=0;i<=n-1;i++){
    		a[i]=a[i+1]*(i+1)%mod;
    	}
    }
    void ITG(ull *a,int n){
    	for(int i=n-1;i>=1;i--){
    		a[i]=a[i-1]*inv[i]%mod;
    	}
    	a[0]=0;
    }
    void NTT(ull *a,int lim,int op){
    	ull x,y;
    	int r;
    	for(int i=0;i<lim;i++){
    		if(i<rev[i]){
    			swap(a[i],a[rev[i]]);
    		}
    	}
    	w[0]=1;
    	for(int mid=1;mid<lim;mid<<=1){
    		r=mid<<1;
    		x=qpow(op==1?g:invg,(mod-1)/r);
    		for(int j=1;j<mid;j++){
    			w[j]=w[j-1]*x%mod;
    		}
    		for(int j=0;j<lim;j+=r){
    			for(int k=j;k-j<mid;k++){
    				x=a[k];
    				y=a[k+mid]%mod*w[k-j]%mod;
    				a[k]=x+y;
    				a[k+mid]=x-y+mod;
    			}
    		}
    		if(mid==(1<<18)){
    			for(int j=0;j<lim;j++){
    				a[j]%=mod;
    			}
    		}
    	}
    	for(int i=0;i<lim;i++){
    		a[i]%=mod;
    	}
    }
    void CROSS(ull *a,ull *b,int n){
    	for(int i=0;i<=n-1;i++){
    		a[i]=a[i]*b[i]%mod;
    	}
    }
    void MUL(ull *a,ull *b,int n){
    	int lim=1,invv;
    	while(lim<n){
    		lim<<=1;
    	}
    	invv=qpow(lim,mod-2);
    	INIT(lim);
    	NTT(a,lim,1);
    	if(a!=b){
    		NTT(b,lim,1);
    	}
    	CROSS(a,b,lim);
    	NTT(a,lim,-1);
    	for(int i=0;i<lim;i++){
    		a[i]=a[i]*invv%mod;
    	}
    	CLR(a+n,lim-n);
    	if(a!=b){
    		CLR(b,lim);
    	}
    }
    void MULT(ull *a,ull *b,int n,int m){
    	REV(b,m);
    	MUL(a,b,n+m);
    	for(int i=0;i<=n-1;i++){
    		a[i]=a[i+m-1];
    	}
    	CLR(a+n,m);
    }
    void INV(ull *a,ull *b,int n){
    	int lim=1,l=0,invv;
    	static ull c[N],d[N];
    	b[0]=qpow(a[0],mod-2);
    	while(lim<n){
    		lim<<=1;
    		l++;
    	}
    	for(int len=2;len<=lim;len<<=1){
    		CLR(c+(len>>1),len>>1);
    		CPY(c,b,len>>1);
    		CPY(d,a,len);
    		INIT(len);
    		NTT(c,len,1);
    		NTT(d,len,1);
    		CROSS(d,c,len);
    		NTT(d,len,-1);
    		invv=qpow(len,mod-2);
    		for(int i=0;i<len;i++){
    			d[i]=d[i]*invv%mod;
    		}
    		CLR(d,len>>1);
    		NTT(d,len,1);
    		CROSS(d,c,len);
    		NTT(d,len,-1);
    		for(int i=len>>1;i<len;i++){
    			b[i]=mod-d[i]*invv%mod;
    		}
    	}
    	for(int i=0;i<lim;i++){
    		b[i]%=mod;
    	}
    	CLR(b+n,lim-n);
    	CLR(c,lim);
    	CLR(d,lim);
    }
    int BSGS(int b,int n,int mod){
    	int t=sqrt(mod)+1,now=1;
    	unordered_map<int,int>mapp;
    	for(int bb=0;bb<=t-1;bb++){
    		mapp[1ll*now*n%mod]=bb;
    		now=1ll*now*b%mod;
    	}
    	b=now;
    	now=1;
    	for(int aa=1;aa<=t;aa++){
    		now=1ll*now*b%mod;
    		if(mapp.count(now)){
    			return aa*t-mapp[now];
    		}
    	}
    	return -1;
    }
    void SQRT(ull *a,ull *b,int n){
    	int lim=1,l=0;
    	static ull c[N],d[N];
    	b[0]=qpow(g,BSGS(g,a[0],mod)/2);
    	b[0]=min(b[0],mod-b[0]);
    	while(lim<n){
    		lim<<=1;
    		l++;
    	}
    	for(int len=2;len<=lim;len<<=1){
    		CPY(c,b,len);
    		INV(c,d,len);
    		CPY(c,a,len);
    		MUL(c,d,len<<1);
    		ADD(b+(len>>1),c+(len>>1),len>>1);
    		for(int i=len>>1;i<len;i++){
    			b[i]=b[i]*inv2%mod;
    		}
    	}
    	CLR(b+n,lim-n);
    	CLR(c,lim);
    }
    void DIV(ull *a,ull *b,int n,int m){
    	static ull c[N],d[N];
    	REV(a,n);
    	REV(b,m);
    	CPY(c,b,n-m+1);
    	INV(c,d,n-m+1);
    	CPY(c,a,n-m+1);
    	MUL(c,d,(n-m+1)<<1);
    	CLR(c+n-m+1,n-m+1);
    	REV(c,n-m+1);
    	CPY(d,c,n-m+1);
    	REV(a,n);
    	REV(b,m);
    	MUL(c,b,n<<1);
    	CLR(c+n,n);
    	DEC(a,c,n);
    	CPY(b,a,m-1);
    	CPY(a,d,n-m+1);
    	CLR(c,n);
    	CLR(d,n-m+1);
    }
    void LN(ull *a,ull *b,int n){
    	static ull c[N];
    	CPY(b,a,n);
    	DRV(b,n);
    	INV(a,c,n);
    	MUL(b,c,n<<1);
    	CLR(b+n,n);
    	ITG(b,n);
    }
    void EXP(ull *a,ull *b,int n){
    	int lim=1;
    	static ull c[N],d[N];
    	b[0]=1;
    	while(lim<n){
    		lim<<=1;
    	}
    	for(int len=2;len<=lim;len<<=1){
    		CPY(c,b,len);
    		CLR(d,len);
    		LN(c,d,len);
    		CLR(c,len);
    		c[0]=1;
    		DEC(c,d,len);
    		ADD(c,a,len);
    		MUL(b,c,len<<1);
    		CLR(b+len,len);
    		CLR(c+len,len);
    	}
    	CLR(b+n,lim-n);
    	CLR(d,lim);
    }
    void POW(ull *a,int n,int k){
    	static ull b[N];
    	LN(a,b,n);
    	for(int i=0;i<=n-1;i++){
    		b[i]=b[i]*k%mod;
    	}
    	CLR(a,n);
    	EXP(b,a,n);
    	CLR(b,n);
    }
    void SIN(ull *a,ull *b,int n){
    	int ii;
    	static ull c[N],d[N]; 
    	CPY(c,a,n);
    	ii=qpow(g,BSGS(g,mod-1,mod)/2);
    	for(int i=0;i<=n-1;i++){
    		c[i]=c[i]*ii%mod;
    	}
    	EXP(c,b,n);
    	CPY(d,b,n);
    	CLR(c,n);
    	INV(d,c,n);
    	DEC(b,c,n);
    	ii=qpow(ii,mod-2);
    	for(int i=0;i<=n-1;i++){
    		b[i]=b[i]*inv2%mod*ii%mod;
    	}
    }
    void COS(ull *a,ull *b,int n){
    	int ii;
    	static ull c[N],d[N];
    	CPY(c,a,n);
    	ii=qpow(g,BSGS(g,mod-1,mod)/2);
    	for(int i=0;i<=n-1;i++){
    		c[i]=c[i]*ii%mod;
    	}
    	EXP(c,b,n);
    	CPY(d,b,n);
    	CLR(c,n);
    	INV(d,c,n);
    	ADD(b,c,n);
    	for(int i=0;i<=n-1;i++){
    		b[i]=b[i]*inv2%mod;
    	}
    }
    void ARCSIN(ull *a,ull *b,int n){
    	static ull c[N],d[N];
    	CPY(b,a,n);
    	DRV(b,n);
    	CPY(c,a,n);
    	MUL(c,c,n<<1);
    	CLR(c+n,n);
    	d[0]=1;
    	DEC(d,c,n);
    	CLR(c,n);
    	SQRT(d,c,n);
    	CLR(d,n);
    	INV(c,d,n);
    	MUL(b,d,n<<1);
    	CLR(b+n,n);
    	ITG(b,n);
    	CLR(c,n<<1);
    	CLR(d,n);
    }
    void ARCTAN(ull *a,ull *b,int n){
    	static ull c[N],d[N];
    	CPY(b,a,n);
    	DRV(b,n);
    	CPY(c,a,n);
    	MUL(c,c,n<<1);
    	CLR(c+n,n);
    	d[0]=1;
    	ADD(d,c,n);
    	CLR(c,n);
    	INV(d,c,n);
    	MUL(b,c,n<<1);
    	CLR(b+n,n);
    	ITG(b,n);
    	CLR(c,n<<1);
    	CLR(d,n);
    }
    void EVALUATION(ull *a,ull *b,int n){
    	static ull c[N],d[N],*q[N];
    	function<void(ull *a,int,int,int)>init=[&](ull *a,int l,int r,int rt){
    		int mid=(l+r)>>1;
    		ull *tmpa=new ull[(r-l+3)<<1](),*tmpb=new ull[(r-l+3)<<1]();
    		q[rt]=new ull[r-l+2];
    		if(l==r){
    			q[rt][0]=1;
    			q[rt][1]=mod-a[l];
    			delete[] tmpa;
    			delete[] tmpb;
    			return;
    		}
    		init(a,l,mid,rt<<1);
    		init(a,mid+1,r,rt<<1|1);
    		CPY(tmpa,q[rt<<1],mid-l+2);
    		CPY(tmpb,q[rt<<1|1],r-mid+1);
    		MUL(tmpa,tmpb,r-l+3);
    		CPY(q[rt],tmpa,r-l+2);
    		delete[] tmpa;
    		delete[] tmpb;
    	};
    	function<void(ull*,ull*,int,int,int)>calc=[&](ull *f,ull *ans,int l,int r,int rt){
    		int mid=(l+r)>>1;
    		ull *a=new ull[(r-l+2)*3](),*b=new ull[(r-l+2)*3]();
    		if(l==r){
    			ans[l]=f[0];
    			delete[] a;
    			delete[] b;
    			return;
    		}
    		CPY(a,f,r-l+1);
    		CPY(b,q[rt<<1|1],r-mid+1);
    		MULT(a,b,r-l+1,r-mid+1);
    		calc(a,ans,l,mid,rt<<1);
    		CPY(a,f,r-l+1);
    		CPY(b,q[rt<<1],mid-l+2);
    		MULT(a,b,r-l+1,mid-l+2);
    		calc(a,ans,mid+1,r,rt<<1|1);
    		delete[] a;
    		delete[] b;
    	};
    	init(b,0,n-1,1);
    	CPY(c,q[1],n);
    	INV(c,d,n);
    	MULT(a,d,n,n);
    	calc(a,b,0,n-1,1);
    }
    void INTERPOLATION(ull *a,ull *b,int n){
    	static ull c[N],d[N],*q[N],*ans[N];
    	function<void(ull *a,int,int,int)>init=[&](ull *a,int l,int r,int rt){
    		int mid=(l+r)>>1;
    		ull *tmpa=new ull[(r-l+2)<<1](),*tmpb=new ull[(r-l+2)<<1]();
    		q[rt]=new ull[r-l+2];
    		if(l==r){
    			q[rt][0]=mod-a[l];
    			q[rt][1]=1;
    			delete[] tmpa;
    			delete[] tmpb;
    			return;
    		}
    		init(a,l,mid,rt<<1);
    		init(a,mid+1,r,rt<<1|1);
    		CPY(tmpa,q[rt<<1],mid-l+2);
    		CPY(tmpb,q[rt<<1|1],r-mid+1);
    		MUL(tmpa,tmpb,r-l+2);
    		CPY(q[rt],tmpa,r-l+2);
    		delete[] tmpa;
    		delete[] tmpb;
    	};
    	function<void(int,int,int)>calc=[&](int l,int r,int rt){
    		int mid=(l+r)>>1;
    		ans[rt]=new ull[r-l+1];
    		if(l==r){
    			ans[rt][0]=1ll*b[l]*qpow(d[l],mod-2)%mod;
    			return;
    		}
    		calc(l,mid,rt<<1);
    		calc(mid+1,r,rt<<1|1);
    		ull *a=new ull[(r-l+1)<<1](),*b=new ull[(r-l+1)<<1]();
    		CPY(a,ans[rt<<1],mid-l+1);
    		CPY(b,q[rt<<1|1],r-mid+1);
    		MUL(a,b,r-l+1);
    		CPY(ans[rt],a,r-l+1);
    		CLR(a,r-l+1);
    		CPY(a,ans[rt<<1|1],r-mid);
    		CPY(b,q[rt<<1],mid-l+2);
    		MUL(a,b,r-l+1);
    		ADD(ans[rt],a,r-l+1);
    		delete[] a;
    		delete[] b;
    	};
    	init(a,1,n,1);
    	CPY(c,q[1],n+1);
    	DRV(c,n+1);
    	CPY(d,a+1,n);
    	EVALUATION(c,d,n);
    	for(int i=n;i>=1;i--){
    		d[i]=d[i-1];
    	}
    	calc(1,n,1);
    	CPY(b,ans[1],n);
    }
    void MOV(ull *a,int n,int m){
    	int pro=1;
    	static ull b[N];
    	static int c[N];
    	for(int i=0;i<=n-1;i++){
    		a[i]=a[i]*ifac[i]%mod*ifac[n-1-i]%mod;
    		if((n-1-i)%2){
    			a[i]=(mod-a[i])%mod;
    		}
    	}
    	for(int i=0;i<=2*(n-1);i++){
    		b[i]=c[i]=qpow(m-(n-1)+i,mod-2);
    	}
    	MUL(a,b,n<<1);
    	for(int i=m;i>=m-(n-1);i--){
    		pro=1ll*pro*i%mod;
    	}
    	for(int i=0;i<=n-1;i++){
    		a[i]=a[i+n-1]*pro%mod;
    		pro=1ll*pro*c[i]%mod*(m+i+1)%mod;
    	}
    	CLR(a+n,n);
    }
    void calc(int l,int r,int rt){
    	int mid=(l+r)>>1;
    	ull *tmpa=new ull[(r-l+2)<<1](),*tmpb=new ull[(r-l+2)<<1]();
    	d[rt]=new ull[r-l+2];
    	if(l==r){
    		d[rt][0]=1;
    		d[rt][1]=mod-p[l];
    		delete[] tmpa;
    		delete[] tmpb;
    		return;
    	}
    	calc(l,mid,rt<<1);
    	calc(mid+1,r,rt<<1|1);
    	CPY(tmpa,d[rt<<1],mid-l+2);
    	CPY(tmpb,d[rt<<1|1],r-mid+1);
    	MUL(tmpa,tmpb,r-l+2);
    	CPY(d[rt],tmpa,r-l+2);
    	delete[] tmpa;
    	delete[] tmpb;
    	delete[] d[rt<<1];
    	delete[] d[rt<<1|1];
    }
    int main(){
    	int n,m,ans=1;
    	scanf("%d%d",&n,&m);
    	fac[0]=inv[1]=1;
    	for(int i=1;i<=n;i++){
    		scanf("%d",&p[i]);
    		fac[i]=1ll*fac[i-1]*i%mod;
    		ans=1ll*ans*p[i]%mod;
    	}
    	ifac[n]=qpow(fac[n],mod-2);
    	for(int i=n-1;i>=0;i--){
    		ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
    	}
    	for(int i=2;i<=n;i++){
    		inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    	}
    	ans=1ll*ans*fac[n-2]%mod;
    	for(int i=0;i<=n-1;i++){
    		a[i]=1ll*ifac[i]*qpow(i+1,m)%mod;
    		b[i]=1ll*ifac[i]*qpow(i+1,2*m)%mod;
    	}
    	INV(a,c,n);
    	MUL(b,c,n<<1);
    	CLR(b+n,n);
    	LN(a,c,n);
    	CLR(a,n);
    	calc(1,n,1);
    	CPY(y,d[1],n+1);
    	CPY(a,y,n+1);
    	DRV(a,n+1);
    	for(int i=n;i>=1;i--){
    		a[i]=a[i-1];
    	}
    	a[0]=0;
    	INV(y,x,n+1);
    	MUL(a,x,(n+1)<<1);
    	CLR(a+n+1,n+1);
    	CLR(y,n+1);
    	y[0]=n;
    	DEC(y,a,n+1);
    	CROSS(b,y,n);
    	CROSS(c,y,n);
    	CLR(a,n+1);
    	EXP(c,a,n);
    	MUL(a,b,n<<1);
    	CLR(a+n,n);
    	printf("%lld",1ll*a[n-2]*ans%mod);
    }
    
    • 1

    信息

    ID
    3764
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者