Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走
题目描述
给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去。
有 \(Q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一直随机游走,直到点集 \(S\) 中所有点都至少经过一次的话,期望游走几步。
特别地,点 \(x\)(即起点)视为一开始就被经过了一次。
答案对 $998244353 $ 取模。
输入格式
第一行三个正整数 \(n,Q,x\)。
接下来 \(n-1\) 行,每行两个正整数 \((u,v)\) 描述一条树边。
接下来 \(Q\) 行,每行第一个数 \(k\) 表示集合大小,接下来 \(k\) 个互不相同的数表示集合 \(S\)。
输出格式
输出 \(Q\) 行,每行一个非负整数表示答案。
数据范围与提示
对于 \(20\%\) 的数据,有 \(1\leq n,Q\leq 5\)。
另有 \(10\%\) 的数据,满足给定的树是一条链。
另有 \(10\%\) 的数据,满足对于所有询问有 \(k=1\)。
另有 \(30\%\) 的数据,满足 \(1\leq n\leq 10 ,Q=1\)。
对于 \(100\%\) 的数据,有 \(1\leq n\leq 18\),\(1\leq Q\leq 5000\),\(1\leq k\leq n\)。
首先根据\(\min-\max\) 反演我们知道:
\]
设\(f_{v,S}\)表示从\(v\)出发,经过\(S\)中至少一个节点的期望步数。
如果\(v\in S\),\(f_{v,S}=0\),否则:
\]
然后这是颗树,我们可以将\(DP\)方程移项变成只与\(fa\)的\(f\)值个一个常数有关。
设:
\]
带回去化简:
(d_v-\sum A_u)*f_v=d_v+f_{fa}+\sum B_u\\
f_v=\frac{1}{d_v-\sum A_u}*f_{fa}+\frac{d_v+\sum B_u}{d_v-\sum A_u}
\]
得到:
\]
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 19
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
const ll mod=998244353;
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
}
int n;
int X,m;
struct road {int to,nxt;}s[N<<1];
int h[N],cnt;
void add(int i,int j) {s[++cnt]=(road) {j,h[i]};h[i]=cnt;}
ll w[N];
int d[N];
ll A[N],B[N],f[N];
int tag[N];
void dfs(int v,int fa) {
A[v]=B[v]=0;
ll sumA=0,sumB=0;
for(int i=h[v];i;i=s[i].nxt) {
int to=s[i].to;
if(to==fa) continue ;
dfs(to,v);
sumA=(sumA+A[to])%mod;
sumB=(sumB+B[to])%mod;
}
if(tag[v]) A[v]=B[v]=0;
else A[v]=ksm(d[v]-sumA+mod,mod-2),B[v]=(d[v]+sumB)*ksm(d[v]-sumA+mod,mod-2)%mod;
}
void dfs2(int v,int fa) {
f[v]=(A[v]*f[fa]+B[v])%mod;
for(int i=h[v];i;i=s[i].nxt) {
int to=s[i].to;
if(to==fa) continue ;
dfs2(to,v);
}
}
int mn[1<<N];
int main() {
n=Get(),m=Get(),X=Get();
int a,b;
for(int i=1;i<n;i++) {
a=Get(),b=Get();
add(a,b),add(b,a);
d[a]++,d[b]++;
}
for(int S=1;S<1<<n;S++) {
for(int i=1;i<=n;i++) if(S>>i-1&1) tag[i]=1;
dfs(1,0),dfs2(1,0);
mn[S]=f[X];
for(int i=1;i<=n;i++) if(S>>i-1&1) tag[i]=0;
}
for(int S=1;S<1<<n;S++) {
int cnt=0;
for(int i=0;i<n;i++) cnt+=S>>i&1;
if(!(cnt&1)) mn[S]=(mod-mn[S])%mod;
}
for(int i=0;i<n;i++) {
for(int S=1;S<1<<n;S++) {
if(S>>i&1) mn[S]=(mn[S]+mn[S^(1<<i)]+mod)%mod;
}
}
while(m--) {
int k=Get();
int sta=0;
while(k--) sta|=1<<Get()-1;
cout<<mn[sta]<<"\n";
}
return 0;
}
Loj #2542. 「PKUWC2018」随机游走的更多相关文章
- 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\)中任意一点的最小期望步数 按照树上高斯消元的套路,我们可以把转移写成\( ...
- 【LOJ】#2542. 「PKUWC2018」随机游走
题解 虽然我知道minmax容斥,但是--神仙能想到把这个dp转化成一个一次函数啊= = 我们相当于求给定的\(S\)集合里最后一个被访问到的点的时间,对于这样的max的问题,我们可以用容斥把它转化成 ...
- 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 ...
随机推荐
- 探究 CSS 混合模式\滤镜导致 CSS 3D 失效问题
今天在写一个小的 CSS Demo,一个关于 3d 球的旋转动画,关于 CSS 3D,少不了会使用下面这几个属性: { transform-style: preserve-3d; perspectiv ...
- cmd中输入net start mysql 提示:服务名无效或者MySQL正在启动 MySQL无法启动
在DOS窗口.gitbush以及一些可以使用的命令行工具的界面上,输入:net stop mysql.net start mysql时,总是提示:服务名无效. 出现提示如下: 原因是:因为net st ...
- vue cli 3.x 项目部署到 github pages
github pages 是 github 免费为用户提供的服务,写博客,或者部署一些纯静态项目. 最近将 vue cli 3.x 初始化项目部署到 github pages,踩了一些坑,记录如下. ...
- RocketMQ4.4.0新特性分享
rocketmq1.架构 MQ历史 由数据结构队列发展而来 MQ使用场景 异步处理 解耦 削峰填谷 数据同步2.队列3.使用 生产 同步(sync) 默认重试2次总共3次 默认等待超时时间为3s 异步 ...
- 【机器学习】--xgboost从初识到应用
一.前述 在 Kaggle 的很多比赛中,我们可以看到很多 winner 喜欢用 xgboost,而且获得非常好的表现,今天就来看看 xgboost 到底是什么以及如何应用.Gradient boos ...
- Java分布式锁,搞懂分布式锁实现看这篇文章就对了
随着微处理机技术的发展,人们只需花几百美元就能买到一个CPU芯片,这个芯片每秒钟执行的指令比80年代最大的大型机的处理机每秒钟所执行的指令还多.如果你愿意付出两倍的价钱,将得到同样的CPU,但它却以更 ...
- Java集合详解1:ArrayList,Vector与Stack
今天我们来探索一下LinkedList和Queue,以及Stack的源码. 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech 喜欢的话麻烦star一下 ...
- 从PRISM开始学WPF(三)Prism-Region-更新至Prism7.1
[7.1update]在开始前,我们先看下版本7.1中在本实例中的改动. 首先,项目文件中没有了Bootstrapper.cs,在上一篇的末尾,我们说过了,在7.1中,不见推荐使用Bootstrapp ...
- 《C#并发编程经典实例》学习笔记—2.2 返回完成的任务
问题: 如何实现一个具有异步签名的同步方法. 从异步接口或基类继承代码,但希望用同步方式实现方法. 解释一下所谓的异步接口和异步基类.例如如下代码 interface IMyAsyncInterfac ...
- MySQL 笔记整理(11) --怎么给字符串字段加索引?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 11) --怎么给字符串字段加索引? 日常工作中的登录系统,你很可能会使 ...