前言

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


正题

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


题目大意

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

\(1\leq n\leq 1000,0\leq p_{i,j}\leq 10^6\)


解题思路

只考虑外向树的话就是水题了,因为显然的\(x\)要排在子树最前面的概率就是\(\frac{w_x}{\sum_{y\in subtree_x}w_y}\)。

然后直接\(n^2\)的\(dp\)就可以力。

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

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

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

额这种树形\(dp\)枚举子树大小可以做到\(n^2\)这个是老生常谈了

时间复杂度\(O(n^2)\)


code

#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;
}

P5405-[CTS2019]氪金手游【树形dp,容斥,数学期望】的更多相关文章

  1. LOJ3124 CTS2019 氪金手游 概率、容斥、树形DP

    传送门 D2T3签到题可真是IQ Decrease,概率独立没想到然后就20pts滚粗了 注意题目是先对于所有点rand一个权值\(w\)然后再抽卡. 先考虑给出的关系是一棵外向树的情况.那么我们要求 ...

  2. p5405 [CTS2019]氪金手游

    题目大意 题意狗屁不通 看毛子语都比看这个题面强 分析 我们假设这棵树是一个内向树 那么我们可以轻易的得到dp[x][i]表示x点子树和为i的期望 转移只需枚举当前期望大小和子树期望大小即可 但是由于 ...

  3. 【题解】Luogu P5405 [CTS2019]氪金手游

    原题传送门 我们珂以先考虑一条链的情况,设\(sum\)为所有\(w_i\)的总和,\(Sw_i\)表示\(\sum_{j=i}^nw_i\) \[1 \rightarrow 2 \rightarro ...

  4. [CTS2019]氪金手游

    [CTS2019]氪金手游 各种情况加在一起 先考虑弱化版:外向树,wi确定 i合法的概率就是wi/sw sw表示子树的w的和,和子树外情况无关 这些概率乘起来就是最终合法的概率 如果都是外向树, f ...

  5. Luogu5405 CTS2019氪金手游(容斥原理+树形dp)

    考虑外向树怎么做.显然设f[i][j]为i子树中出现权值和为j的合法方案的概率,转移做树形背包即可. 如果树上只有一条反向边,显然可以先不考虑该边计算概率,再减去将整棵树看做外向树的概率.于是考虑容斥 ...

  6. [LOJ#3119][Luogu5405][CTS2019]氪金手游(DP+容斥)

    先考虑外向树的做法,显然一个点在其子树内第一个出现的概率等于它的权值除以它子树的权值和.于是f[i][j]表示i的子树的权值和为j时,i子树内所有数的相互顺序都满足条件的概率,转移直接做一个背包卷积即 ...

  7. 题解-CTS2019氪金手游

    Problem \(\mathtt {loj-3124}\) 题意概要:给定 \(n\) 个点,\(w_i\) 分别有 \(p_{i,1},p_{i,2},p_{i,3}\) 的概率取 \(1,2,3 ...

  8. HDU - 5977 Garden of Eden (树形dp+容斥)

    题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...

  9. bzoj 4455 [Zjoi2016]小星星 树形dp&容斥

    4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 643  Solved: 391[Submit][Status] ...

随机推荐

  1. wpf 中的style

    我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法和数据的载体.控件的算法主要体现在可以激发的事件.可 ...

  2. WPF 绘图 和动画

    wpf 的动画:https://www.cnblogs.com/TianFang/p/4050845.html

  3. SSM整合二

    总结 <!-- 批量删除 --> <delete id="deleteAll"> delete from tbl_emp where emp_id in & ...

  4. [SWMM]软件启动不了,出现 “ RPC服务器不可用 ” 错误

    [问题]打开SWMM5.1软件时,初选"RPC服务器不可用"的错误 [解决]计算机管理--服务 设置Print Spooler服务状态为启动,并设置为自启动.

  5. Difference between trustStore and keyStore in Java - SSL

    Difference between trustStore and keyStore in Java - SSL   trustStore vs keyStore in Java trustStore ...

  6. 读vue-cli3 官方文档的一些学习记录

    原来一直以为vue@cli3 就是创建模板的工具,读了官方文档才知道原来这么有用,不少配置让我长见识了 Prefetch 懒加载配置 懒加载相信大家都是知道的,使用Import() 语法就可以在需要的 ...

  7. Go并发控制--Channel篇

    目录 1. 前言 2. 使用channel控制子协程 2.1 使用场景 2.2 总结 1. 前言 我们考虑这么一种场景,协程A执行过程中需要创建子协程A1.A2.A3-An,协程A创建完子协程后就等待 ...

  8. 在EXCEL中,判断同列数据重复,并标识出来

    推荐方法:建立辅助列,查找B列数据是否重复.=IF(COUNTIF(B:B,B1)>1,"重复","")按住公式单元格右下角实心十字,向下拖拽复制公式.= ...

  9. 快速入门PaddleOCR,并试用其开发一个搜题小工具

    介绍 PaddleOCR 是一个基于百度飞桨的OCR工具库,包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别.竖排文本识别.长文本识别.同时支持多种文本检测.文本识别的训练算法. ...

  10. java agent简介

    java agent简介 主要就是两种,一种的方法是premain,一种是agentmain.这两种的区别是: premain是在jvm启动的时候类加载到虚拟机之前执行的 agentmain是可以在j ...