P8967 追寻 | Pursuit of Dream 题解
P8967 追寻 | Pursuit of Dream
很久没做过这种酸爽的推式子题了。
首先可以确定的是,看似每个点的坐标的每个维度都是
对于期望 DP,一般是逆推的方法。考虑设一个
直接到达终点
显然前者较为好算,我们先来计算前者,也就是直接到达终点的期望。
对于一个点
还有一点需要注意,我们要保证这
想要走完这
于是这部分的期望步数就是
出现散入天际
首先可以确定的是,不能使
但是注意到,不管从哪里散入天际,这个期望都是恒定的。也就是说,“散入天际之后到达终点” 这一部分的期望和
到这一步,
前者的计算是一个很典的结论,如下:
用求导可证明。后一部分的计算参考我们上文计算的结果,走到终点的期望步数是
于是我们得到了
酸爽推式子
发现
把
再整理得:
于是我们只需知道
#include<bits/stdc++.h>
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define inv(x) power(x,MOD-2)
using namespace std;
char buf[1<<20],*p1=buf,*p2=buf;
int read(){
int x=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x;
}
using ll=long long;
constexpr int MAXN=105,MAXK=10005,MAXV=1e7+5;
constexpr ll MOD=998244353,inv8=205817851;
int n,k;
ll d[MAXN],a[MAXK][MAXN],p[MAXK],P,invP,s[MAXK],q[MAXK];
ll fac[MAXV];
ll power(ll a,ll b){
ll res=1;
for(;b;a=a*a%MOD,b>>=1)if(b&1)res=res*a%MOD;
return res;
}
void init(){
fac[0]=1;
for(int i=1;i<MAXV;i++) fac[i]=fac[i-1]*i%MOD;
}
void add(ll&x,ll y){
x=(x+y>=MOD?x+y-MOD:x+y);
}
int main(){
init();
n=read(),k=read();
for(int i=1;i<=n;i++) d[i]=read(),s[0]+=d[i];
for(int i=1;i<=k;i++){
for(int j=1;j<=n;j++){
a[i][j]=read();
if(d[j]<a[i][j]) s[i]=-1;
else if(~s[i]) s[i]+=d[j]-a[i][j];
}
p[i]=inv8*read()%MOD;
add(P,p[i]);
}
invP=inv(P);
ll res1,res2=0,g;
for(int i=0;i<=k;i++){
if(~s[i]){
q[i]=fac[s[i]]*power((1-P+MOD)%MOD,s[i])%MOD*inv(power(n,s[i]))%MOD;
for(int j=1;j<=n;j++) q[i]=q[i]*inv(fac[d[j]-a[i][j]])%MOD;
}
add(res2,p[i]*invP%MOD*((1-q[i]+MOD)%MOD)%MOD);
}
res1=(1-res2+MOD)%MOD;
res2=res2*invP%MOD;
g=res2*inv(res1)%MOD;
printf("%lld\n",(1-q[0]+MOD)%MOD*((g+invP)%MOD)%MOD);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】