LOJ #2542「PKUWC2018」随机游走
$ Min$-$Max$容斥真好用
$ PKUWC$滚粗后这题一直在$ todolist$里
今天才补掉..还要更加努力啊..
题意:给一棵不超过$ 18$个节点的树,$ 5000$次询问,每次问从根随机游走走遍一个集合的期望步数
$ Solution:$
考虑$ Min$-$Max$容斥
有$ Max(S)=\sum\limits_{T \subseteq S}(-1)^{|T|+1}Min(T)$
其中$ S,T$是一个集合,$Max(S)$表示$ S$中最大元素,$Min(S)$同理
$ update$评论区已经给出证明
我们设集合$ S$表示走到每个点的期望时间
显然走遍一个集合的期望时间就是$ Max(S)$
且第一次走到某集合的期望时间是$ Min(S)$
$ Max(S)$不容易计算,我们转而求解$ Min(S)$
令$f_i$表示从点$ i$随机游走第一次走到集合$ S$的期望步数
这个显然可以高斯消元,不过复杂度略大
由于转移是在树上,可以直接在树上$ O(n)$消元
我们令$ f_i=k_if_{fa[i]}+b_i$
当$ i$在集合$ S$中的时候$k_i=b_i=0$否则进行转移
转移的时候把当前点孩子的$ k$和$ b$算出然后代到当前点的方程中算出当前点的$ k$和$ b$
这样可以在$O(2^n·n*算逆元复杂度)$的时间复杂度内算出所有的$ Min(S)$
然后直接容斥算$ Max(S)$,复杂度是$ 5000*2^n$的
我们可以提前预处理每个$ Max(S)$每次枚举子集转移,时间复杂度是$ 3^n$的
据说都能过
不过其实这部分可以优化到$ 2^n*n$的
我们直接根据$ popcount(S)$的奇偶性来判断是否给$ Min(S)$乘上$ -1$
然后直接高维前缀和即可
$ my \ code:$
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define p 998244353
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int i,j,k,m,n,x,y,z,cnt,Root;
struct ret{
int k,b;//k*father + b
ret operator +(const ret s)const{
return {(k+s.k)%p,(b+s.b)%p};
}
ret operator *(const int s)const{
return {1ll*k*s%p,1ll*b*s%p};
}
}f[][<<];
int F[],L[],N[],a[],d[],inv[],Min[<<];
void add(int x,int y){
a[++k]=y;
if(!F[x])F[x]=k;
else N[L[x]]=k;
L[x]=k;
}
int ksm(int x,int y){
int ans=;
for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*x*ans%p;;
return (ans+p)%p;
}
ret dfs(int x,int pre,int s){
if(s>>x-&)return{,};
ret now={,};
for(rt i=F[x];i;i=N[i])if(a[i]!=pre)now=now+dfs(a[i],x,s)*inv[d[x]];
const int Inv=ksm(-now.k,p-);
return {1ll*Inv*inv[d[x]]%p,1ll*Inv*(now.b+)%p};
}
#define cnt(x) __builtin_popcount(x)
int main(){
n=read();int Q=read();Root=read();
inv[]=inv[]=;
for(rt i=;i<=;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p;
for(rt i=;i<n;i++){
x=read();y=read();
add(x,y);
add(y,x);
d[x]++;d[y]++;
}
for(rt i=;i<(<<n);i++){
ret ans=dfs(Root,Root,i);
Min[i]=ans.b*(cnt(i)&?:-);
}
for(rt i=;i<n;i++)
for(rt j=;j<<<n;j++)if(j>>i&)(Min[j]+=Min[j^(<<i)])%=p;
while(Q--){
x=read();int sum=;
for(rt i=;i<=x;i++)
sum|=(<<read()-);
writeln((Min[sum]+p)%p);
}
return ;
}
LOJ #2542「PKUWC2018」随机游走的更多相关文章
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- 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 ...
随机推荐
- 树结构关系的数据导出为excel
该文针对的是关于树结构的数据的导出,每一个节点都可以创建不定数的子节点,在选择好某个节点进行导出 时,会把该节点以及子节点的数据都导出来.导出后的excel的格式大概如下图的形式,这个是一个比较理想 ...
- matlab 下标类型
double int uint time: double = int < uint8 较为神奇. clear clc time=clock; a=zeros(,); : a(i)=; end f ...
- HTML学习笔记Day12
一.CSS3基础 (一)css3概念及优势 概念:CSS3是css技术的升级版本,CSS3语言开发是朝着模块化发展的.以前的规范作为一个模块实在是太庞大而且比较复杂,所以,把它分解为一些小的模块,更多 ...
- (数学 尾0的个数) 51nod1003 阶乘后面0的数量
n的阶乘后面有多少个0? 6的阶乘 = 1*2*3*4*5*6 = 720,720后面有1个0. 收起 输入 一个数N(1 <= N <= 10^9) 输出 输出0的数量 输入样例 5 ...
- python自动化开发-[第二十五天]-scrapy进阶与flask使用
今日内容概要 1.cookie操作 2.pipeline 3.中间件 4.扩展 5.自定义命令 6.scrapy-redis 7.flask使用 - 路由系统 - 视图 - 模版 - message( ...
- Vue computed属性
computed vs methods 我们可以使用Vue中的method计算出学科的总分,最终得到的总数结果是相同的. 在上例的基础上,我们把computed区块中的totalMarks函数整体移到 ...
- Reference-TMB
Paper Name:Targeted Next Generation Sequencing Identifies Markers of Response to PD-1 Blockade Adress ...
- eclipse设置是否自动跳转切换到debug视图模式
之前一直用公司二次封装的eclipse,这几天用原生态的eclipse,刚开始使用eclipse进行调试时,会自动跳转到debug视图.后来不小心关闭了,就不会自动切换到debug视图. 这个小问题之 ...
- 利用 JMetal 实现大规模聚类问题的研究(一)JMetal配置
研究多目标优化问题,往往需要做实验来对比效果,所以需要很多多目标方面的经典代码,比如NSGA-II, SPEA, MOEA,MOEA/D, 或者PSO等等. 想亲自实现这些代码,非常浪费时间,还有可能 ...
- zookeeper的Java端API应用
1. 基本使用 org.apache.zookeeper.Zookeeper是客户端入口主类,负责建立与server的会话.它提供了表1所示几类主要方法: 功能 描述 create 在本地目录树中创建 ...