P5405-[CTS2019]氪金手游【树形dp,容斥,数学期望】

0|1前言

话说在Loj下了个数据发现这题的名字叫fgo

在这里插入图片描述


1|0正题

题目链接:https://www.luogu.com.cn/problem/P5405


1|1题目大意

n张卡的权值为1/2/3的概率权重分别是px,1/2/3,然后按照权值每次获得一张未获得的卡,然后再该出一棵有向树(方向可以都是外向或内向的),求所有每条边(u,v)u都比v先获得的概率。

1n1000,0pi,j106


1|2解题思路

只考虑外向树的话就是水题了,因为显然的x要排在子树最前面的概率就是wxysubtreexwy

然后直接n2dp就可以力。

但是现在有内向边怎么办,还是考虑转换成只有外向的,也就是去掉一种限制。

去掉一种限制的话容斥是一个不错的办法,考虑的话就是恰好若干条指定边(内向边),我们可以指定至少k跳内向边不满足条件,这样就组成了一个外向森林,可以很容易处理出答案,而且这样的容斥系数就是(1)k

然后直接dp就得了,设fi,j表示到节点i然后权值和是j,如果限制一条内向边就直接乘上一个1就好了。

额这种树形dp枚举子树大小可以做到n2这个是老生常谈了

时间复杂度O(n2)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1100,P=998244353; struct node{ ll to,next,w; }a[N<<1]; ll n,tot,ans,ls[N],siz[N],w[N][3],f[N][3*N],g[N*3]; ll power(ll x,ll b){ ll ans=1; while(b){ if(b&1)ans=ans*x%P; x=x*x%P;b>>=1; } return ans; } void addl(ll x,ll y,ll w){ a[++tot].to=y; a[tot].next=ls[x]; a[tot].w=w; ls[x]=tot;return; } void dp(ll x,ll fa){ ll d=power(w[x][0]+w[x][1]+w[x][2],P-2); siz[x]=3; f[x][1]=w[x][0]*d%P; f[x][2]=w[x][1]*d*2ll%P; f[x][3]=w[x][2]*d*3ll%P; for(ll e=ls[x];e;e=a[e].next){ ll y=a[e].to; if(y==fa)continue; dp(y,x); if(a[e].w){ for(ll i=1;i<=siz[x];i++) for(ll j=1;j<=siz[y];j++) (g[i+j]-=f[x][i]*f[y][j]%P)%=P,(g[i]+=f[x][i]*f[y][j]%P)%=P; } else{ for(ll i=1;i<=siz[x];i++) for(ll j=1;j<=siz[y];j++) (g[i+j]+=f[x][i]*f[y][j]%P)%=P; } siz[x]+=siz[y]; for(ll i=1;i<=siz[x];i++) f[x][i]=g[i],g[i]=0; } for(int i=1;i<=siz[x];i++) f[x][i]=f[x][i]*power(i,P-2)%P; return; } signed main() { scanf("%lld",&n); for(ll i=1;i<=n;i++) scanf("%lld%lld%lld",&w[i][0],&w[i][1],&w[i][2]); for(ll i=1;i<n;i++){ ll x,y;scanf("%lld%lld",&x,&y); addl(x,y,0);addl(y,x,1); } dp(1,0); for(ll i=1;i<=siz[1];i++) (ans+=f[1][i])%=P; printf("%lld\n",(ans+P)%P); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14974373.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(28)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示