【LOJ】#2542. 「PKUWC2018」随机游走
题解
虽然我知道minmax容斥,但是……神仙能想到把这个dp转化成一个一次函数啊= =
我们相当于求给定的\(S\)集合里最后一个被访问到的点的时间,对于这样的max的问题,我们可以用容斥把它转化成min问题
也就是
\(max{S} = \sum_{T \subset S} (-1)^{|T| + 1}min{T}\)
然后我们变成要求对给定的集合,最早访问到其中的点的期望
设当前的点集为\(S\),\(f(u)\)为从u点出发最早到\(S\)中的点期望的步数
如果\(u \in S\)
\(f(u) = 0\)
否则
\(f(u) = \frac{1}{d[u]}(f(fa[u]) + 1)+ \frac{1}{d[u]}\sum (f(ch[u]) + 1)\)
我们发现,从叶子节点开始倒推,我们每个点都可以表示成
\(f(u) = A_u f(fa[u]) + B_u\)的式子
那么我们把这个式子代进去
设\(v\)代表\(u\)的儿子
\((1 - \frac{\sum A_{v}}{d[u]})f(u) = \frac{1}{d[u]}f(fa[u]) + (1 + \frac{\sum B_{v}}{d[u]})\)
从叶子开始倒退即可,我们把起点当根,那么答案就是起点的\(B_x\)
最后用FMT累加起来可以做到\(O(1)\)回答询问(也可以子集枚举累加)
复杂度\(O(n 2^n + Q)\)
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define pb push_back
#define MAXN 100005
#define mo 974711
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 - '0' + c;
c = getchar();
}
res = res * f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
const int MOD = 998244353;
int N,Q,st,A[25],B[25],D[25],cnt,f[(1 << 18) + 5],inv[20];
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int fpow(int x,int c) {
int t = x,res = 1;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
struct node {
int to,next;
}E[105];
int head[20],sumE;
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
void dp(int u,int fa,int S) {
if(S >> (u - 1) & 1) {++cnt;}
A[u] = B[u] = 0;
int SumA = 0,SumB = 0;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dp(v,u,S);
SumA = inc(SumA,A[v]);
SumB = inc(SumB,B[v]);
}
}
if(S >> (u - 1) & 1) return;
int m = inc(1,MOD - mul(SumA,inv[D[u]]));
m = fpow(m,MOD - 2);
int k = inc(1,mul(SumB,inv[D[u]]));
A[u] = mul(inv[D[u]],m);
B[u] = mul(k,m);
}
void Solve() {
read(N);read(Q);read(st);
int u,v;
for(int i = 1 ; i < N ; ++i) {
read(u);read(v);
add(u,v);add(v,u);
++D[u];++D[v];
}
inv[1] = 1;
for(int i = 2 ; i <= N ; ++i) {
inv[i] = mul(inv[MOD % i],(MOD - MOD / i));
}
for(int S = 1 ; S < (1 << N) ; ++S) {
cnt = 0;
dp(st,0,S);
if((cnt + 1) & 1) f[S] = MOD - B[st];
else f[S] = B[st];
out(f[S]);space;
}
enter;
for(int i = 1 ; i < (1 << N) ; i <<= 1) {
for(int j = 1 ; j < (1 << N) ; ++j) {
if(j & i) f[j] = inc(f[j],f[j ^ i]);
}
}
int k,S;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
颓颓颓颓颓
【LOJ】#2542. 「PKUWC2018」随机游走的更多相关文章
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- LOJ #2542「PKUWC2018」随机游走
$ Min$-$Max$容斥真好用 $ PKUWC$滚粗后这题一直在$ todolist$里 今天才补掉..还要更加努力啊.. LOJ #2542 题意:给一棵不超过$ 18$个节点的树,$ 5000 ...
- loj#2542. 「PKUWC2018」随机游走(树形dp+Min-Max容斥)
传送门 首先,关于\(Min-Max\)容斥 设\(S\)为一个点的集合,每个点的权值为走到这个点的期望时间,则\(Max(S)\)即为走遍这个集合所有点的期望时间,\(Min(S)\)即为第一次走到 ...
- LOJ 2542 「PKUWC2018」随机游走 ——树上高斯消元(期望DP)+最值反演+fmt
题目:https://loj.ac/problem/2542 可以最值反演.注意 min 不是独立地算从根走到每个点的最小值,在点集里取 min ,而是整体来看,“从根开始走到点集中的任意一个点就停下 ...
- loj#2542. 「PKUWC2018」随机游走(MinMax容斥 期望dp)
题意 题目链接 Sol 考虑直接对询问的集合做MinMax容斥 设\(f[i][sta]\)表示从\(i\)到集合\(sta\)中任意一点的最小期望步数 按照树上高斯消元的套路,我们可以把转移写成\( ...
- LOJ2542. 「PKUWC2018」随机游走
LOJ2542. 「PKUWC2018」随机游走 https://loj.ac/problem/2542 分析: 为了学习最值反演而做的这道题~ \(max{S}=\sum\limits_{T\sub ...
- 「PKUWC2018」随机游走(min-max容斥+FWT)
「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...
- 「PKUWC2018」随机游走
题目 我暴力过啦 看到这样的东西我们先搬出来\(min-max\)容斥 我们设\(max(S)\)表示\(x\)到达点集\(S\)的期望最晚时间,也就是我们要求的答案了 显然我们也很难求出这个东西,但 ...
- loj2542「PKUWC2018」随机游走
题目描述 给定一棵 nn 个结点的树,你从点 xx 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 QQ 次询问,每次询问给定一个集合 SS,求如果从 xx 出发一直随机游走,直到点集 SS ...
随机推荐
- vs配置SP++3.0
最近在研究信号处理的C语言算法,突然发现一个西安交大的师兄之前已经写出来了一个完整的库,同样是研究生三年,差别怎么这样大呢. 先从用轮子开始吧. 一.SP++3.0安装及测试 官网下载地址: http ...
- seaborn基础整理
seaborn是基于matplotlib的更高级的做图工具,下面主要针对以下几个部分进行整理: 第一部分:https://douzujun.github.io/page/%E6%95%B0%E6%8D ...
- OpenResty 扩展库之(一)——lua-resty-shell 库
介绍 当您需要执行子进程(或shell命令)时,这是一个打算与OpenResty应用程序一起使用的小型库. 它类似于os.execute和io.popen,除了它是完全非阻塞的,因此即使对于需要很长时 ...
- python 分布式进程体验
抽了点时间体验了一把python 分布式进程,有点像分布式计算的意思,不过我现在还没有这个需求,先把简单体验的脚本发出来,供路过的各位高手指教 注:需要先下载multiprocessing 的pyth ...
- HDU 4500 小Q系列故事——屌丝的逆袭
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4500 解题报告:简单题,数据范围不大,直接暴力每个点,然后再比较出得分最大的点的位置和分数. #inc ...
- Django框架下的小人物--Cookie
1. 什么是Cookie,它的用途是什么? Cookies是一些存储在用户电脑上的小文件.它是被设计用来保存一些站点的用户数据,这样能够让服务器为这样的用户定制内容,后者页面代码能够获取到Cookie ...
- Linux操作系统介绍
1Linux操作系统介绍 1.1linux系统的应用 服务器系统:Web应用服务器.数据库服务器.接口服务器.DNS.FTP等等: 嵌入式系统:路由器.防火墙.手机.PDA.IP 分享器.交换器.家电 ...
- Pool thread stack traces: Thread[C3P0PooledConnectionPoolManager[identityToken->原因解决办法
今天本地连接测试库测试,发现早上还是好的,下午就崩了,报这个错,使用的是c3po连接池: , 纠结了好久,发现是数据库连接用光了,很多人都在连,果断换了本地库,好使了,看百度说把macPoolSizz ...
- 【HASPDOG】Communication error
靠,防火墙没关,关了防火墙生成文件成功
- 读书笔记 effective C++ Item 33 避免隐藏继承而来的名字
1. 普通作用域中的隐藏 名字实际上和继承没有关系.有关系的是作用域.我们都知道像下面的代码: int x; // global variable void someFunc() { double x ...