【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 ...
随机推荐
- layoutSubviews何时被调用
layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews 但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时, ...
- JAVA-JSP动作
动作元素基本上是预定义的功能.下表列出了可用的JSP动作 - 编号 动作 描述 1 jsp:include 在请求页面时包含一个文件. 2 jsp:useBean 查找或实例化一个JavaBean. ...
- SVN不能提交代码
Error: Some resources were not reverted. Attempted to lock an already-locked dir svn: Working copy ' ...
- android onActivityResult的执行
1.如果activity中重写了onActivityResult函数,同时添加在该activity的fragment也重写了onActivtyResult函数,那么会执行Activity的onActi ...
- JAVA编程之——反射Reflect
说到反射,首先要说一下Java中的类和对象. 在Java中万事万物皆对象(有两个 例外,一个是普通数据类型,另一个是静态的东西,静态的东西不是对象的,是属于类的). 在Java中,类也是对象,类是ja ...
- 重新找回spyder3-editor 里的code completion
升级到spyder3之后, 突然丢失了code autocompletion在editor context里. 觉得太不爽了. 虽然在ipython窗格里TAB键的自动完成功能依然完好. 仔细观察 T ...
- asp.net WebForm程序删除.designer.cs文件之后的故事
1.介绍 正常情况下添加一个WebForm程序结构如下(命名为:myWebForm.aspx) 文件说明:.aspx文件:书写html代码部分,以及javascript,css等代码书写及引用 .as ...
- Entity Framework Context上下文管理(CallContext 数据槽)
Context上下文管理 Q1:脏数据 Q2:一次逻辑操作中,会多次访问数据库,增加了数据库服务器的压力 >在一次逻辑操作中实现上下文实例唯一 方法一:单例模式:内存的爆炸式增长 在整个运行期间 ...
- Groovy/Spock 测试导论
Groovy/Spock 测试导论 原文 http://java.dzone.com/articles/intro-so-groovyspock-testing 翻译 hxfirefox 测试对于软件 ...
- 2016.6.18——Implement strStr()
Implement strStr() 本题收获: 1.考虑多种边界条件. 2.haystack.size() size_type 是无符号的,即为正数 在32位系统上定义为 unsigned int ...