Problem

loj2542

题意:一棵 \(n\) 个结点的树,从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去,询问走完一个集合 \(S\)的期望时间,多组询问

\(n\leq 18,Q\leq 5000\)

Solution

首先来个\(min-max\)容斥

一下是看错题时想的

然后预处理从每个点开始的到达每个点的所有集合的期望,\(O(n^22^n)\)卡常可过

  • 若是这样,前20pts可以搞出来了:对于每次询问在线处理dp数组,利用最值容斥搞事情
  • 30pts的部分是条链,可以对于每个部分做一次集合前缀后缀预处理
  • 40pts的部分每次只询问一个点,明显可以预处理
  • 事实上70pts的部分最简单,直接上容斥即可

    接下来是100pts……

    目前最暴力复杂度为\(O(n^22^n+\sum 2^{k_i})\),若数据随机,期望状态下每次仅需计算\(\sum_{i=1}^n\frac {2^i\binom ni}{2^n}\approx 1478\)次,即总共大约需要计算\(18^2\times 2^{18}+5000\times 1478=92324656\leq 10^8\)次,理论可过,但出题人十有八九将其卡掉了(网上说没卡)

上头是看看错题的情况下想的,实际上所有询问中起点只可能有一个

重新理一遍思路:由于要\(min-max\)反演,即到达集合\(S\)中最后到达点的时间可以转化为\(2^{|S|}\)个子集中最先到达点的时间进行容斥,再容斥即可

考虑如何求每个集合中最先到达点的期望时间,由期望的性质可得(设\(f[x]\)表示从\(x\)点出发到达第一个集合点的时间期望,\(v\)表示与\(x\)相连的节点,\(d_i\)表示\(i\)点的度数):

\[f_x=\frac 1{d_x}\sum_v{(f_v+1)}
\]

由于需要对所有\(2^n\)个集合都做dp,酱紫求一次需要高斯消元\(n^3\),但总复杂度\(O(n^32^n)\approx 1.5\times 10^9\)一定接受不了

发现目前为止还没有利用最重要的一个性质:这是一棵树

要快速求解\(f_x\)数组,就需要一定的优化,由于这张图是一棵树,即每两点之间的路径是唯一的,可设\(f_x=Af_{t}+B\)(其中\(t\)为\(x\)的父亲)

利用上边的式子列出方程(设\(c\)为\(x\)的儿子):

\[f_x=\frac 1{d_x}\bigl[f_t+1+\sum_{x\rightarrow c}(f_c+1)\bigr]
\]

由于儿子加父亲节点一共\(d_x\)个,即

\[f_x=\frac 1{d_x}(f_t+\sum_{x\rightarrow c}f_c)+1
\]

我们要解出\(A,B\),所以需要将\(f_x=Af_t+B\)代入式子

\[f_x=\frac 1{d_x}\bigl[f_t+\sum_{x\rightarrow c}(A_cf_x+B_c)\bigr]+1
\]

\[(d_x-\sum_{x\rightarrow c} A_c)f_x=f_t+\sum_{x\rightarrow c}B_c+d_x
\]

\[f_x=\frac 1{d_x-\sum A_c}f_t+\frac {\sum B_c+d_x}{d_x-\sum A_c}
\]

解得:

\[\left\{
\begin{aligned}
A_x & = \frac 1{d_x-\sum A_c} \\
B_x & = \frac {\sum B_c+d_x}{d_x-\sum A_c}
\end{aligned}
\right.\]

再加上集合\(S\)内的点\(x\)满足\(A_x=B_x=0\)

然后对于每个集合 \(S\) 就可以 \(O(n)\) 地求出从任意点出发到达第一个集合内点的期望时间

这样询问就可以愉悦地 \(\mathrm{min-max}\) 容斥了

\(O(1)\) 查询的话只需要高维前缀和一下即可,于是乎总时间复杂度为 \(O(n2^n+Q)\)

upd:好像还要算上求逆元,复杂度 \(O(n2^n\log p+Q)\),算出来大概 \(1.5e8\),但由于枚举集合后一旦走到集合就递回,再算上快速幂的小常数,完全可过(复杂度跑不满,跑得最满的情况是菊花图,但即便是菊花图,常数最大也就 \(\frac 12\))

Code

#include <cstdio>
#include <cctype> inline void read(int&x){
char c11=getchar();x=0;while(!isdigit(c11))c11=getchar();
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();
} const int N=19,M=1<<18,p=998244353;
struct Edge{int v,nxt;}a[N*N];
int k[N],b[N],deg[N],head[N];
int f[M],bit[M],n,Q,st,_; inline int qpow(int A,int B){
int res(1);
while(B){
if(B&1)res=1ll*res*A%p;
A=1ll*A*A%p,B>>=1;
}return res;
} inline void pls(int&A,int B){A=A+B<p?A+B:A+B-p;}
inline void dec(int&A,int B){A=A-B<0?A-B+p:A-B;} void dfs(int x,int las,int lim){
if(lim&(1<<x-1)){k[x]=b[x]=0;return ;}
k[x]=b[x]=deg[x];
for(int i=head[x];i;i=a[i].nxt)
if(a[i].v!=las){
dfs(a[i].v,x,lim);
dec(k[x],k[a[i].v]);
pls(b[x],b[a[i].v]);
}
k[x]=qpow(k[x],p-2);
b[x]=1ll*b[x]*k[x]%p;
} int main(){
read(n),read(Q);read(st);int lim=1<<n;
for(int i=1,x,y;i<n;++i){
read(x),read(y),++deg[x],++deg[y];
a[++_].v=y,a[_].nxt=head[x],head[x]=_;
a[++_].v=x,a[_].nxt=head[y],head[y]=_;
}
for(int S=1;S<lim;++S){
bit[S]=bit[S>>1]+(S&1);
dfs(st,0,S);
f[S]=(bit[S]&1?b[st]:p-b[st]);
}
for(int i=1;i<lim;i<<=1)
for(int j=0;j<lim;++j)
if(i&j)pls(f[j],f[i^j]); int t,x,s;
while(Q--){
read(t),s=0;
while(t--)read(x),s|=1<<x-1;
printf("%d\n",f[s]);
}
return 0;
}

题解-PKUWC2018 随机游走的更多相关文章

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

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

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

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

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

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

  4. [PKUWC2018] 随机游走

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

  5. [LOJ#2542] [PKUWC2018] 随机游走

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

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

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

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

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

  8. LOJ2542 PKUWC2018随机游走(概率期望+容斥原理)

    如果直接dp,状态里肯定要带上已走过的点的集合,感觉上不太好做. 考虑一种对期望的minmax容斥:其中Max(S)为遍历完S集合的期望步数,Min(S)为遍历到S集合中一个点的期望步数.当然才不管怎 ...

  9. [LOJ2542][PKUWC2018]随机游走(MinMax容斥+树形DP)

    MinMax容斥将问题转化为求x到S中任意点的最小时间. 树形DP,直接求概率比较困难,考虑只求系数.最后由于x节点作为树根无父亲,所以求出的第二个系数就是答案. https://blog.csdn. ...

随机推荐

  1. ACM-ICPC 2018 焦作赛区网络预赛 I Save the Room(水题)

    https://nanti.jisuanke.com/t/31718 题意 问能否用1*1*2的长方体填满a*b*c的长方体. 分析 签到.如果a.b.c都是奇数,一定不能. #include< ...

  2. vue加载本地json文件

    背景:做地区跟行业级联下拉选择,因为想做成可以搜索的,所以必须一次加载数据,后台有做memcache缓存,但因为数据量大,还是比较费时间,所以做成本地文件,简单记录一下 准备数据,放到static下 ...

  3. HDB3编码器

    一.HDB3 码介绍 三阶高密度双极性码(英语:High Density Bipolar of Order 3 code,简称:HDB3码)是一种适用于基带传输的编码方式.它是一种 AMI 码的改进型 ...

  4. MYSQL数据库安装记

    这回安装数据库装,做下记录. 1.下载mysql源安装包 shell> wget http://dev.mysql.com/get/mysql57-community-release-el7-8 ...

  5. 最好用的js前端框架、组件、文档在线预览插件

    这里收集的都是个人认为比较好的js框架.组件 js前端ui框架 此处列举出个人认为最好的几个框架(排序即排名),现在好点的框架商用都需要付费,以下几个也不例外,但是由于组件丰富,都可以作为企业应用的完 ...

  6. Java SE之I/O流:知识框架

  7. 深入理解jQuery中的each方法

    写在前面 我们先回顾一下数组中的forEach方法吧.在数组的实例上有个forEach方法供所有实例使用,forEach里面接收一个回调函数,而且回调函数默认接收三个参数:当前项,索引,数组 .for ...

  8. 5.28 js基础 简介

    Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) JavaScript历史背景介绍 布 ...

  9. Leetcode#771.Jewels and Stones(宝石与石头)

    题目描述 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字 ...

  10. Python 的异步 IO:Asyncio 简介

    转载自https://segmentfault.com/a/1190000008814676 好文章 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时, ...