列表

详情


NC247071. 233玩游戏

描述

你正在玩一个有n轮的游戏。初始等级为1级,血量为。在每一轮游戏中,如果等级为x,生命值为y,有p的概率升级。升级时,等级将升级为,血量将减少o,同时此轮游戏结束。由于最高等级是2级,所以当你的等级为2级并升级时,你的血量将变为0,游戏立即结束。如果你在本轮游戏中没有升级,你有的概率血量减少1,本轮游戏结束。

计算轮后血量为t的概率,答案对998244353取模。

输入描述

第一行五个正整数 n,a,b,t,o,其中 

输出描述

输出n行每行一个数代表答案

示例1

输入:

3 1 2 1 2

输出:

0
0
825631267

说明:

初始时血量为5,要3回合后血量变为1,显然要其中一回合血量扣2,其余两回合血量扣1
第一回合晋升:\frac{1}{2}*\frac{1}{6}*\frac{1}{4}
第二回合晋升:\frac{1}{10}*\frac{1}{2}*\frac{1}{4}
第三回合晋升:\frac{1}{10}*\frac{1}{8}*\frac{1}{2}

答案为\frac{19}{480}

示例2

输入:

6 2 3 5 2

输出:

0
341991121
367875198
935930697
494879403
867916762

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 1371ms, 内存消耗: 7820K, 提交时间: 2022-12-09 22:02:01

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010,mod=998244353,G=3;
int n,o,a,b,t,p;
typedef long long ll;
int qmi(int a,int b){
	int r=1;
	for(;b;b>>=1){
		if(b&1)r=(ll)r*a%mod;
		a=(ll)a*a%mod;
	}
	return r;
}
namespace Poly{
	typedef vector<int>Poly;
	int w1[30],w2[30],ny2[30];
	void init(){
		int v=mod-1;
		for(int i=0;i<=23;i++){
			w1[i]=qmi(G,v),w2[i]=qmi(w1[i],mod-2),ny2[i]=qmi(1<<i,mod-2);
			v>>=1;
		}
	}
	void FFT(Poly&a,int lmt,int tp){
		int y=1<<lmt;a.resize(y);
		vector<int>rev,tmp;
		rev.resize(y),tmp.resize(y);
		for(int i=1;i<y;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lmt-1));
		for(int i=0;i<y;i++)
			if(i>rev[i])swap(a[i],a[rev[i]]);
		tmp[0]=1;
		for(int i=1;i<=lmt;i++){
			int len=1<<i,mid=len>>1,w=tp==1?w1[i]:w2[i];
			for(int j=1;j<mid;j++)tmp[j]=(ll)tmp[j-1]*w%mod;
			for(int j=0;j<y;j+=len)
				for(int k=0;k<mid;k++){
					int u=a[j+k],v=(ll)a[j+k+mid]*tmp[k]%mod;
					a[j+k]=(u+v)%mod,a[j+k+mid]=(u-v+mod)%mod;
				}
		}
		if(tp==-1)for(int i=0;i<y;i++)a[i]=(ll)a[i]*ny2[lmt]%mod;
	}
	Poly mul(Poly a,Poly b){
		int lmt=ceil(log2(a.size()+b.size()-1)),s=a.size()+b.size()-1;
		FFT(a,lmt,1),FFT(b,lmt,1);
		for(int i=0;i<(1<<lmt);i++)a[i]=(ll)a[i]*b[i]%mod;
		FFT(a,lmt,-1);
		a.resize(s);
		return a;
	}
	template<class Fir,class Iter>
	Poly newton(int n,const Poly&f,Fir fir,Iter iter){
		Poly res(1);
		res[0]=fir(f[0]);
		int t=1;
		while(t<n)iter(t,f,res);
		res.resize(n);
		return res;
	} 
	Poly Ni(int n,const Poly&f){
		return newton(n,f,
			[&](int v){
				assert(v!=0);
				return qmi(v,mod-2);
			},
			[&](int&t,const Poly&f,Poly&res){
				t<<=1;
				Poly nf;nf.resize(t);
				for(int i=0;i<min((int)f.size(),t);i++)nf[i]=f[i];
				nf=mul(nf,res);nf.resize(t);
				for(int&i:nf)i=(mod-i)%mod;
				nf[0]=(nf[0]+2)%mod;
				res=mul(res,nf);
				res.resize(t);
			}
		);
	}
	Poly Ln(int n,const Poly&f){
		assert(f[0]==1);
		Poly f1(n),fn;
		for(int i=0;i<min(n-1,(int)f.size()-1);i++)f1[i]=(ll)(i+1)*f[i+1]%mod;
		fn=Ni(n,f);
		f1=mul(f1,fn);f1.resize(n);
		for(int i=n-1;i;i--)f1[i]=(ll)f1[i-1]*qmi(i,mod-2)%mod;
		f1[0]=0;
		return f1;
	}
	Poly exp(int n,const Poly&f){
		return newton(n,f,
			[&](int v){
				assert(v==0);
				return 1;
			},
			[&](int&t,const Poly&f,Poly&res){
				t<<=1;
				Poly lf=Ln(t,res);
				for(int&i:lf)i=(mod-i)%mod;
				lf[0]=1;
				for(int i=0;i<min((int)f.size(),t);i++)lf[i]=(lf[i]+f[i])%mod;
				res=mul(res,lf);
				res.resize(t);
			}
		);
	}
	Poly qmi(int n,const Poly&f,int k){
		if(k==0){
			Poly res(n);
			res[0]=1;
			return res;
		}
		int cur=0;
		while(cur<(int)f.size()&&f[cur]==0)cur++;
		if(cur==(int)f.size())return Poly(n);
		Poly f1(n);
		for(int i=cur;i<min(n,(int)f.size());i++)f1[i-cur]=f[i];
		if((ll)cur*k>=n){
			return Poly(n);
		}
		cur*=k;
		assert(f1[0]!=0);
		int p=f1[0],q=::qmi(p,mod-2);
		for(int&i:f1)i=(ll)i*q%mod;
		f1=Ln(n,f1);
		for(int&i:f1)i=(ll)i*k%mod;
		f1=exp(n,f1);
		p=::qmi(p,k);
		for(int&i:f1)i=(ll)i*p%mod;
		for(int i=n-1;i>=cur;i--)f1[i]=f1[i-cur];
		for(int i=0;i<cur;i++)f1[i]=0;
		return f1;
	}
};
int jc[N],ny[N];
int C(int x,int y){
	return (ll)jc[x]*ny[y]%mod*ny[x-y]%mod;
}

vector<int>solve(int l,int r){
	if(l==r)return {1,(int)(mod-(ll)(l-1)*qmi(l,mod-2)%mod)};
	int mid=(l+r)>>1;
	return Poly::mul(solve(l,mid),solve(mid+1,r));
}
vector<int>f;
void Solve1(){
	f=solve(t,n+o);
	f=Poly::Ni(n+1,f);
	cerr<<"F "<<(ll)f[n]*qmi(qmi(2,mod-2),n)%mod<<'\n';
}
vector<int>g;
int ff[800],now;
inline void Add(int&x,int y){
	x=(x+y>=mod?x+y-mod:x+y);
}
int vv[N+800];
void Del(int x){
	for(int i=1;i<=now;i++)Add(ff[i],(ll)ff[i-1]*vv[x]%mod);
	now--;
}
void Insert(int x){
	now++;
	for(int i=now;i;i--)Add(ff[i],mod-(ll)ff[i-1]*vv[x]%mod);
}
void Solve2(){
	if(n<t)return;
	int cur=n+o-1;
	g.resize(o+1);
	ff[0]=1;now=0;
	int v1=n+o;
	for(int i=n+o;i-o>=t;i--){
//		v1=1;
//		for(int j=i;j>i-o;j--)v1=(ll)v1*j%mod;
//		for(int j=i-1;j>i-o;j--)Insert(j);
//		for(int j=0;j<=now;j++)Add(g[j],(ll)ff[j]*v1%mod);
//		for(int j=i-1;j>i-o;j--)Del(j);
		if(i<n+o){
			Del(i);
		}
		while(cur>i-o){
			v1=(ll)v1*cur%mod;
			Insert(cur--);
		}
		for(int j=0;j<=now;j++)Add(g[j],(ll)ff[j]*v1%mod);
		v1=(ll)v1*qmi(i,mod-2)%mod;
	}
//	cerr<<"FF "<<f.size()<<' '<<g.size()<<'\n';
	g=Poly::mul(f,g);
}
int CV1,CV2;
int calc1(){
	int v=1;
	for(int i=n+o;i>t;i--)v=(ll)v*qmi(i,mod-2)%mod;
	return v;
}
int calc2(){
	int v=1;
	for(int i=n+o;i>t;i--)v=(ll)v*qmi(i,mod-2)%mod;
	return v;
}
int get1(int x){
	if(n+o-t>x)return 0;
	int v=(ll)f[x-(n+o-t)]*CV1%mod*qmi((1-p+mod)%mod,x)%mod;
	return v;
}
int get2(int x){
	if(n<t)return 0;
	if(n-t>x-1)return 0;
	int v=(ll)g[x-1-(n-t)]*CV2%mod*qmi((1-p+mod)%mod,x-1)%mod*p%mod;
	return v;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin>>n>>a>>b>>t>>o;
	p=(ll)a*qmi(b,mod-2)%mod;
	for(int i=1;i<=n+o;i++)vv[i]=(ll)(i-1)*qmi(i,mod-2)%mod;
	
	Poly::init();
	
	int r=1;
	r=(ll)r*qmi(qmi(2,mod-2),n)%mod;
	r=(ll)r*qmi((ll)(n+o-1)*qmi(n+o,mod-2)%mod,n)%mod;
	Solve1(),Solve2();
	CV1=calc1(),CV2=calc2();
	for(int i=1;i<=n;i++){
		cout<<(get1(i)+get2(i))%mod<<'\n';
	}
}

上一题