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\)。

Orz

首先根据\(\min-\max\) 反演我们知道:

\[\max(S)=\sum_{T\subseteq S}(-1)^{|T|-1}\min(T)
\]

设\(f_{v,S}\)表示从\(v\)出发,经过\(S\)中至少一个节点的期望步数。

如果\(v\in S\),\(f_{v,S}=0\),否则:

\[f_v=1+\frac{1}{d_v}f_{fa}+\frac{1}{d_v}\sum f(u)\\
\]

然后这是颗树,我们可以将\(DP\)方程移项变成只与\(fa\)的\(f\)值个一个常数有关。

设:

\[f(v)=A_v*f_{fa}+B_v\\
\]

带回去化简:

\[f_v=1+\frac{1}{d_v}f_{fa}+\frac{1}{d_v}\sum (A_u*f_v+B_u)\\
(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}
\]

得到:

\[A_v=\frac{1}{d_v-\sum A_u},B_v=\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」随机游走的更多相关文章

  1. LOJ #2542「PKUWC2018」随机游走

    $ Min$-$Max$容斥真好用 $ PKUWC$滚粗后这题一直在$ todolist$里 今天才补掉..还要更加努力啊.. LOJ #2542 题意:给一棵不超过$ 18$个节点的树,$ 5000 ...

  2. loj#2542. 「PKUWC2018」随机游走(树形dp+Min-Max容斥)

    传送门 首先,关于\(Min-Max\)容斥 设\(S\)为一个点的集合,每个点的权值为走到这个点的期望时间,则\(Max(S)\)即为走遍这个集合所有点的期望时间,\(Min(S)\)即为第一次走到 ...

  3. LOJ 2542 「PKUWC2018」随机游走 ——树上高斯消元(期望DP)+最值反演+fmt

    题目:https://loj.ac/problem/2542 可以最值反演.注意 min 不是独立地算从根走到每个点的最小值,在点集里取 min ,而是整体来看,“从根开始走到点集中的任意一个点就停下 ...

  4. loj#2542. 「PKUWC2018」随机游走(MinMax容斥 期望dp)

    题意 题目链接 Sol 考虑直接对询问的集合做MinMax容斥 设\(f[i][sta]\)表示从\(i\)到集合\(sta\)中任意一点的最小期望步数 按照树上高斯消元的套路,我们可以把转移写成\( ...

  5. 【LOJ】#2542. 「PKUWC2018」随机游走

    题解 虽然我知道minmax容斥,但是--神仙能想到把这个dp转化成一个一次函数啊= = 我们相当于求给定的\(S\)集合里最后一个被访问到的点的时间,对于这样的max的问题,我们可以用容斥把它转化成 ...

  6. LOJ2542. 「PKUWC2018」随机游走

    LOJ2542. 「PKUWC2018」随机游走 https://loj.ac/problem/2542 分析: 为了学习最值反演而做的这道题~ \(max{S}=\sum\limits_{T\sub ...

  7. 「PKUWC2018」随机游走(min-max容斥+FWT)

    「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...

  8. 「PKUWC2018」随机游走

    题目 我暴力过啦 看到这样的东西我们先搬出来\(min-max\)容斥 我们设\(max(S)\)表示\(x\)到达点集\(S\)的期望最晚时间,也就是我们要求的答案了 显然我们也很难求出这个东西,但 ...

  9. loj2542「PKUWC2018」随机游走

    题目描述 给定一棵 nn 个结点的树,你从点 xx 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 QQ 次询问,每次询问给定一个集合 SS,求如果从 xx 出发一直随机游走,直到点集 SS ...

随机推荐

  1. Ftp修改为主被动模式命令

    FTP是有两种数据连接模式的,主动模式和被动模式. PORT(主动)方式:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路.当需要传送数据时,客户端在命令链路上用 ...

  2. Abnormal build process termination--解决IDEA启动web项目报错

    iDEA启动后报Error:Abnormal build process terminatio 报错的原因如下: Error:Abnormal build process termination: & ...

  3. 20190415 - iOS11 无法连接到 App Store 的解决办法

    问题:更新 iOS 11 后,打开 App Store 提示: 无法连接至 app store 解决: 进入 iOS 系统[设置][iTunes Store 与 App Store],退出当前登录用户 ...

  4. MIP 2016年终总结

    MIP 项目组成立至今已经有一年多的时间,在过去的一年里,感谢各位的关注. 1. MIP JS 迭代 MIP JS 运行环境是 MIP 页面和 MIP 组件运行的基石.在 2016 年 4 月,MIP ...

  5. 快速构建SPA框架SalutJS--项目工程目录 一

    起因 刚进公司那会儿,接的是一个微信APP应用,SPA是前人搭起来的,用到的技术主要是backbone和zepto.后来那人走了,就卤煮一个人把项目接了下来.项目越是到后面,越发觉了诸多弊端,不停的增 ...

  6. 从零开始学习和改造activiti流程引擎的13天,自己记录一下

    day#1(11.13) 尝试通过spring boot 集成最新版activiti 7,但是苦于官方的文档基本为空,无法完成spring boot的配置,最终按照activiti 6的文档,手工初始 ...

  7. PHP面向对象特性

    目录 创建对象 成员属性 成员方法 构造方法 析构方法 垃圾回收机制 访问修饰符 魔术方法 对象比较 继承 重载 属性重载 方法重写 属性重写 静态属性 静态方法 多态 类型约束 抽象类 接口 fin ...

  8. 鸟哥Linux私房菜基础学习篇学习笔记3

    鸟哥Linux私房菜基础学习篇学习笔记3 第十二章 正则表达式与文件格式化处理: 正则表达式(Regular Expression) 是通过一些特殊字符的排列,用以查找.删除.替换一行或多行文字字符: ...

  9. python3 - 文本读音器

    本篇分享的是使用python3制作一个文本读音器,简单点就是把指定的文本文字转语音说出来:做这么个小工具主要是为了方便自己在平时看一些文章眼累的时候,可通过语音来帮助自己,当然如果你是小说迷,可以扩展 ...

  10. 详解IPTABLES

    详解IPTABLES Iptables 是Linux 内核集成的 IP 信息包过滤系统.如果Linux 系统连接到因特网或 LAN.服务器或连接 LAN 和因特网的代理服务器, 则该系统有利于在 Li ...