搞了一下午 真的是啥都不会

首先这道题要用到Min-Max容斥 得到的结论是

设 \(Max(S)\)表示集合里最晚被访问的节点被访问的期望步数

设 \(Min(S)\)表示集合里最早被访问的节点被访问的期望步数

那么$ Max(S) = ∑_{T \in S} {-1^ { \lvert T \rvert+1} }Min(T)$

(这个相关的证明和理解可以看看HDU4336 附一个题解)

考虑对于一个集合\(S\)如何计算\(Min(S)\)

记\(d_u\)为点\(u\)的度数

当\(u\notin S \space\space \Rightarrow \space \space\displaystyle f_u=f_{fa[u]}+1+\sum (f_{son[u]}+1)\times \frac{1}{d_u}\)

当\(u \in S\space\space \Rightarrow \space \space f(u)=0\)

对于树上的期望可以写成$f_u=k_u\times f_{fa[u]}+b_u \(的形式
于是\)\sum f_{son[u]}=\sum_{fa[v]=u}(a_v \times f_u+b_v)$

代入之前的式子并化简得

\(\displaystyle (1-\frac{\sum A_v}{d_u}) f(u) = \frac{1}{d_u}f_{\mathrm{fa}[u]}+(1+\frac{B_v}{d_u})\)

这个\(dfs\)一遍就可以维护所有点的\(a,b\)了

考虑如何回答询问

可以对于每个询问的集合\(S\)暴力枚举子集 这样是可以过得

但我们也可以像类似\(FMT\)的做法先维护出所有集合的子集之和再\(O(1)\)回答每个询问 这里注意每个集合初值的正负

#include<bits/stdc++.h>
using namespace std;
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define pa pair<int,int>
#define mod 998244353
#define ll long long
#define mk make_pair
#define pb push_back
#define lb double
#define fi first
#define se second
#define cl(x) memset(x,0,sizeof x)
#ifdef Devil_Gary
#define bug(x) cout<<(#x)<<" "<<(x)<<endl
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define bug(x)
#define debug(...)
#endif
const int INF = 0x7fffffff;
const int N=1e6+5;
const int M=25;
/*
char *TT,*mo,but[(1<<15)+2];
#define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
inline int read(){
int x=0,rev=0,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return rev?-x:x;
}
struct Edge{
int v,nxt;
}e[N<<1];
int n,Q,rt,tot,head[M],bin[N],a[M],b[M],bit[N],d[M],f[N];
void add(int u,int v){
e[++tot].v=v,e[tot].nxt=head[u],head[u]=tot,++d[u];
e[++tot].v=u,e[tot].nxt=head[v],head[v]=tot,++d[v];
}
int poww(int x,int y){
int ans=1;
while(y){
if(y&1) ans=(ll)ans*x%mod;
y>>=1,x=(ll)x*x%mod;
}
return ans;
}
void dfs(int x,int fa,int S){
a[x]=b[x]=0;
if((1<<x)&S) return;
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].v;
if(j==fa) continue;
dfs(j,x,S);
(a[x]+=a[j])%=mod,(b[x]+=b[j])%=mod;
}
int tmp=poww((1+mod-(ll)a[x]*d[x]%mod)%mod,mod-2);
a[x]=(ll)tmp*d[x]%mod,b[x]=(ll)(1+(ll)b[x]*d[x]%mod)*tmp%mod;
// cout<<x<<" "<<a[x]<<" "<<b[x]<<endl;
}
int main(){
#ifdef Devil_Gary
freopen("in.txt","r",stdin);
#endif
n=read(),Q=read(),rt=read()-1;
for(int i=1;i<n;i++) add(read()-1,read()-1);
for(int i=0;i<n;i++) d[i]=poww(d[i],mod-2);
for(int i=1;i<(1<<n);i++) bin[i]=bin[i>>1]+(i&1);
for(int i=0;i<(1<<n);i++) dfs(rt,-1,i),f[i]=bin[i]&1?b[rt]:(mod-b[rt])%mod;
// for(int i=0;i<(1<<n);i++) cout<<i<<" "<<f[i]<<endl;
for(int j=0;j<n;j++) for(int i=0;i<(1<<n);i++) if(i&(1<<j)) (f[i]+=f[i^(1<<j)])%=mod;
while(Q--){
int S=0;
for(int T=read();T;T--) S|=(1<<(read()-1));
// bug(S);
printf("%d\n",f[S]);
}
}

LOJ2542 随机游走 Min-Max容斥+树上期望DP的更多相关文章

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

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

  2. 【LOJ#2542】[PKUWC2018]随机游走(min-max容斥,动态规划)

    [LOJ#2542][PKUWC2018]随机游走(min-max容斥,动态规划) 题面 LOJ 题解 很明显,要求的东西可以很容易的进行\(min-max\)容斥,那么转为求集合的\(min\). ...

  3. 【洛谷5643】[PKUWC2018] 随机游走(Min-Max容斥+待定系数法+高维前缀和)

    点此看题面 大致题意: 从一个给定点出发,在一棵树上随机游走,对于相邻的每个点均有\(\frac 1{deg}\)的概率前往.多组询问,每次给出一个点集,求期望经过多少步能够访问过点集内所有点至少一次 ...

  4. 洛谷 P5643 - [PKUWC2018]随机游走(Min-Max 容斥+FWT+树上高斯消元,hot tea)

    题面传送门 一道挺综合的 hot tea,放到 PKUWC 的 D2T2 还挺喜闻乐见的( 首先我们考虑怎样对一个固定的集合 \(S\) 计算答案,注意到我们要求的是一个形如 \(E(\max(S)) ...

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

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

  6. 【LOJ2542】【PKUWC 2018】随机游走 min-max容斥 树上高斯消元

    题目描述 有一棵 \(n\) 个点的树.你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一 ...

  7. LOJ2542 PKUWC2018 随机游走 min-max容斥、树上高斯消元、高维前缀和、期望

    传送门 那么除了D1T3,PKUWC2018就更完了(斗地主这种全场0分的题怎么会做啊) 发现我们要求的是所有点中到达时间的最大值的期望,\(n\)又很小,考虑min-max容斥 那么我们要求从\(x ...

  8. LOJ #2542 [PKUWC2018]随机游走 (概率期望、组合数学、子集和变换、Min-Max容斥)

    很好很有趣很神仙的题! 题目链接: https://loj.ac/problem/2542 题意: 请自行阅读 题解首先我们显然要求的是几个随机变量的最大值的期望(不是期望的最大值),然后这玩意很难求 ...

  9. 【LOJ2542】「PKUWC2018」随机游走

    题意 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一 ...

随机推荐

  1. 在Linux,误删磁盘分区怎么恢复呢【转】

    在我们运维工作中,频繁的操作,可能命令写入错误,造成磁盘分区的删除,那么应该怎么办呢?怎么恢复磁盘分区呢? 一不小心删除了磁盘分区.如下图,删除了sda磁盘的第一个分区,为系统boot分区,系统如果重 ...

  2. Ubuntu Eclipse C++运行问题:launch failed.Binary not found

    在Ubuntu下的Eclipse C++环境出现launch failed.Binary not found问题时,可采用如下解决方案: (1)首先检查系统中是否成功安装g++.如果console输出 ...

  3. 018_nginx_proxy死循环问题

    今天线上遇到一个请求一次,触发多次的请求,而且直接把nginx机器压垮了.经排查,经过如下: 一. server{ server www.jyall.com; location /latestrele ...

  4. centos6.5环境通达OA数据库mysql5.0.67升级至mysql5.5.48方案

    centos6.5环境通达OA数据库mysql5.0.67升级至mysql5.5.42方案 整体方案: 环境准备,在备用服务器安装mysql5.5数据库 1.停用生产环境的应用访问 直接修改web的访 ...

  5. lvs持久连接及防火墙标记实现多端口绑定服务

    lvs持久连接及防火墙标记实现多端口绑定服务 LVS持久连接: PCC:将来自于同一个客户端发往VIP的所有请求统统定向至同一个RS: PPC:将来自于一个客户端发往某VIP的某端口的所有请求统统定向 ...

  6. IntelliJ IDEA 下的svn配置及使用的非常详细的图文总结

    首先,使用的时候,自己得先在电脑上安装个小乌龟.也就是svn啦. 第一步安装小乌龟. 如下: 具体安装好像没什么具体要求,一路next,就好. 如上图箭头所示,在安装 TortoiseSVN 的时候, ...

  7. InnoDB的关键特性-插入缓存,两次写,自适应hash索引

    InnoDB存储引擎的关键特性包括插入缓冲.两次写(double write).自适应哈希索引(adaptive hash index).这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性. ...

  8. poj2823 单调队列初步

    什么是单调队列:头元素一直是队列当中的最大值,队列中的值按照递减顺序排列,可以从末尾插入一个元素,或从两段删除元素 1.插入元素,为了保证队列的单调性(这里假设为递减性),在插入元素v时要将对位的元素 ...

  9. js改变或添加className

    js改变或添加className <style type="text/css"> .newDiv { font-weight: bold; } </style&g ...

  10. spring-boot集成spring-data-jpa

    参考这个就行, http://blog.csdn.net/wazz753/article/details/72472411 ps:集成过程中pom文件,我加入的内容如下,两个都需要,实体类记得加注解和 ...