\(\mathcal{Description}\)

  Link.

  有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \(p_{i,k}\)。依照此规则确定权值后,你不停抽卡,每次抽到第 \(i\) 张卡牌的概率正比于 \(w_i\),直到所有卡都被抽过至少一次。

  此后,记 \(t_i\) 表示第 \(i\) 张牌第一次被抽到的时间。给定 \(n-1\) 条形如 \(\lang u,v\rang\) 的限制,表示 \(t_u<t_v\),保证 \(\lang u,v\rang\) 构成的有向图的基图是一棵树。得到的 \(\{t_n\}\) 满足限制的概率,答案模 \(998244353\)。

  \(n\le10^3\)。

\(\mathcal{Solution}\)

  其实是 trick + 板子,但是没见过的话使得想一会儿。

  考虑若树是严格外向树怎么做,这时点 \(u\) 要满足的条件有且仅有「对于所有 \(u\) 子树内的结点 \(v\),\(t_u<t_v\)」。设 \(u\) 子树内的点权和已经确定为 \(s_u\),\(w_u\) 也已确定,则概率显然为 \(\frac{w_u}{s_u}\)。继而得到 DP:令 \(f(u,i)\) 表示 \(u\) 子树内点权和为 \(i\) 时,子树内合法的概率,转移时需要注意 \(\frac{w_u}{s_u}\) 需要转化成条件概率(或者除掉再把新的乘上去)。

  接下来走进一般情况,仍然如外向树般,钦定一个根 \(r\),把指向 \(r\) 的边理解为外向树边“反向”,对于这些边,如果按照正常的外向树做 DP,就相当于「钦定这条限制合法」;如果忽略这条边,就相当于「这条限制不一定合法」,最后能得到「至少有一些限制不合法」,那么带着容斥系数做 DP 就行。复杂度 \(\mathcal O(wn^2)\)。

\(\mathcal{Code}\)

/*+Rainybunny+*/

#include <bits/stdc++.h>

#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i) const int MAXN = 1e3, MOD = 998244353;
int ecnt = 1, n, m, head[MAXN + 5], pr[MAXN + 5][3], inv[MAXN * 3 + 5];
int siz[MAXN + 5], f[MAXN + 5][MAXN * 3 + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5]; inline void link(const int u, const int v) {
graph[++ecnt].to = v, graph[ecnt].nxt = head[u], head[u] = ecnt;
graph[++ecnt].to = u, graph[ecnt].nxt = head[v], head[v] = ecnt;
} inline void subeq(int& u, const int v) { (u -= v) < 0 && (u += MOD); }
inline int mul(const int u, const int v) { return 1ll * u * v % MOD; }
inline int sub(int u, const int v) { return (u -= v) < 0 ? u + MOD : u; }
inline void addeq(int& u, const int v) { (u += v) >= MOD && (u -= MOD); }
inline int add(int u, const int v) { return (u += v) < MOD ? u : u - MOD; }
inline int mpow(int u, int v) {
int ret = 1;
for (; v; u = mul(u, u), v >>= 1) ret = mul(ret, v & 1 ? u : 1);
return ret;
} inline void solve(const int u, const int fa) {
siz[u] = 1;
rep (i, 1, 3) f[u][i] = mul(i, pr[u][i - 1]);
for (int i = head[u], v; i; i = graph[i].nxt) {
if ((v = graph[i].to) != fa) {
solve(v, u); static int tmp[MAXN * 3 + 5];
rep (j, 1, siz[u] * 3) rep (k, 1, siz[v] * 3) {
int t = mul(f[u][j], f[v][k]);
if (i & 1) subeq(tmp[j + k], t), addeq(tmp[j], t);
else addeq(tmp[j + k], t);
}
siz[u] += siz[v];
rep (j, 1, siz[u] * 3) f[u][j] = tmp[j], tmp[j] = 0;
}
}
rep (i, 1, siz[u] * 3) f[u][i] = mul(f[u][i], inv[i]);
} int main() {
scanf("%d", &n);
rep (i, 1, n) {
int s = 0;
rep (j, 0, 2) scanf("%d", &pr[i][j]), s += pr[i][j];
s = mpow(s, MOD - 2);
rep (j, 0, 2) pr[i][j] = mul(s, pr[i][j]);
}
rep (i, 2, n) {
int u, v; scanf("%d %d", &u, &v);
link(u, v);
} inv[1] = 1;
rep (i, 2, 3 * n) inv[i] = mul(inv[MOD % i], MOD - MOD / i);
solve(1, 0); int ans = 0;
rep (i, 1, siz[1] * 3) addeq(ans, f[1][i]);
printf("%d\n", ans);
return 0;
}

Solution -「CTS 2019」「洛谷 P5404」氪金手游的更多相关文章

  1. 「区间DP」「洛谷P1043」数字游戏

    「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...

  2. 「CTS2019 | CTSC2019」氪金手游 解题报告

    「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...

  3. Loj #3124. 「CTS2019 | CTSC2019」氪金手游

    Loj #3124. 「CTS2019 | CTSC2019」氪金手游 题目描述 小刘同学是一个喜欢氪金手游的男孩子. 他最近迷上了一个新游戏,游戏的内容就是不断地抽卡.现在已知: - 卡池里总共有 ...

  4. 「CTS2019」氪金手游

    「CTS2019」氪金手游 解题思路 考场上想出了外向树的做法,居然没意识到反向边可以容斥,其实外向树会做的话这个题差不多就做完了. 令 \(dp[u][i]\) 表示单独考虑 \(u\) 节点所在子 ...

  5. Solution -「JSOI 2019」「洛谷 P5334」节日庆典

    \(\mathscr{Description}\)   Link.   给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的).   \(|S|\le3\time ...

  6. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

  7. Solution -「POI 2010」「洛谷 P3511」MOS-Bridges

    \(\mathcal{Description}\)   Link.(洛谷上这翻译真的一言难尽呐.   给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...

  8. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

  9. 「洛谷5290」「LOJ3052」「十二省联考 2019」春节十二响【启发式合并】

    题目链接 [洛谷传送门] [LOJ传送门] 题目大意 给定一棵树,每次选取树上的一个点集,要求点集中的每个点不能是另一个点的祖先,选出点集的代价为点集中权值最大点的权值,问将所有点都选一遍的最小代价为 ...

随机推荐

  1. Java Date 类型比较

    //某时间Date time = tRemind.getTime();//现在时间Date now = new Date();//结果大于0则是现在时间大于某时间//结果等于0则为刚好相等//结果小于 ...

  2. 安霸pipeline简述之YUV域的处理

    YUV域处理模块的详细介绍: YUV域的处理主要是rgb_to_yuv_matrix,chroma_scale,ASF(空域降噪),MCTF(时域降噪),SharpenB(锐化模块). RGB2YUV ...

  3. XCTF-反序列化中_wakeup()函数

    跳过_wakeup()魔法函数__wakeup(): 将在序列化之后立即被调用漏洞原理: 当反序列化字符串中,表示属性个数的值大于其真实值,则跳过__wakeup()执行 对于该题,先可以看到类xct ...

  4. leetcode 54. 螺旋矩阵 及 59. 螺旋矩阵 II

    54. 螺旋矩阵 问题描述 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, ...

  5. ctf--web刷题记录 ACTF2020back up file 、极客大挑战2019php、secret file

    ACTF2020back up file backup file指的是备份文件,一般备份文件的后缀有".git" .".svn"." .swp&quo ...

  6. Android 12(S) 图形显示系统 - 基本概念(一)

    1 前言 Android图形系统是系统框架中一个非常重要的子系统,与其它子系统一样,Android 框架提供了各种用于 2D 和 3D 图形渲染的 API供开发者使用来创建绚丽多彩的应用APP.图形渲 ...

  7. C# 季节判断

    编写一个控制台应用程序,可根据输入的月份判断所在季节. 代码如下 using System; using System.Collections.Generic; using System.Linq; ...

  8. java原码、反码、补码、位运算

    1.对于有符号的数(java中的数都是有符号的) 二进制的最高位是符号位:0表示正数,1表示负数 正数的原码,反码,补码都一样 负数的反码=它的原码符号位不变,其它位取反 负数的补码=它的反码+1 0 ...

  9. 技巧02--Terminal Preview优化

    0x00 下载安装 可在MS应用商店安装,也可以直接百度下载安装包安装 0x01 设置默认自启 0x02 Terminal Preview美化 1.打开终端settings 2.点击这个Open JS ...

  10. 聊聊HTTPS和SSL协议

    本文为转载,原文链接http://www.techug.com/https-ssl-tls,作者不详. 要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识. 1. 大致了解几个基本术语(H ...