「PKUWC2018」随机游走
我暴力过啦
看到这样的东西我们先搬出来\(min-max\)容斥
我们设\(max(S)\)表示\(x\)到达点集\(S\)的期望最晚时间,也就是我们要求的答案了
显然我们也很难求出这个东西,但是我们有\(min-max\)容斥
设\(min(S)\)表示\(x\)第一次到达\(S\)的期望时间,我们就有
\]
我们现在只需要求出所有\(min(S)\)之后用\(fwt\)做一个子集和就好了
尽管这是一棵树,但是我并没有推出什么优美的转移方程,我们考虑暴力高消
设\(dp_{x,s}\)表示从\(x\)到集合\(s\)的期望步数
显然如果有\(x\in s\),那么\(dp_{x,s}=0\)
否则
\]
于是我们对于每一种\(s\)分别列方程转移就好了
复杂度是\(O(2^{n}n^3)\)
但是我们注意到没有包含\(x\)点的集合只有\(2^{n-1}\)个,同时高消的常数小至\(\frac{1}{8}\),同时很多高消都没有跑满,于是还是跑的挺快的
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=998244353;
struct E{int v,nxt;}e[40];
int num,n,Q,X,len;
int dp[262145];
int head[19],d[19];
int cnt[262145];
int a[20][20],id[20],vis[20],to[20],inv[20],ans[20];
inline int ksm(int a,int b) {
int S=1;
while(b) {if(b&1) S=1ll*S*a%mod;b>>=1;a=1ll*a*a%mod;}
return S;
}
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
inline void solve(int S) {
int t=0;memset(vis,0,sizeof(vis));
for(re int i=1;i<=n;i++) {
if(S&(1<<(i-1))) continue;
vis[i]=1;id[++t]=i;to[i]=t;
}
if(!vis[X]) return;
memset(a,0,sizeof(a));
for(re int i=1;i<=t;i++) {
int x=id[i];
for(re int j=head[x];j;j=e[j].nxt)
if(vis[e[j].v]) a[i][to[e[j].v]]=inv[d[x]];
a[i][i]=mod-1;a[i][t+1]=mod-1;
}
for(re int i=1;i<=t;i++) {
int p=i;
for(p=i;p<=t;p++) if(a[p][i]) break;
if(p!=i) std::swap(a[i],a[p]);
int now=ksm(a[i][i],mod-2);
for(re int j=n+1;j>=i;--j) a[i][j]=1ll*a[i][j]*now%mod;
for(re int j=i+1;j<=t;j++)
for(re int k=t+1;k>=i;--k) {
a[j][k]=(a[j][k]-1ll*a[j][i]*a[i][k]%mod);
if(a[j][k]<0) a[j][k]=(a[j][k]+mod)%mod;
}
}
ans[t]=a[t][t+1];
for(re int i=t-1;i>=0;--i) {
ans[i]=a[i][t+1];
for(re int j=i+1;j<=t;j++) {
ans[i]-=1ll*a[i][j]*ans[j]%mod;
if(ans[i]<0) ans[i]=(ans[i]+mod)%mod;
}
}
dp[S]=ans[to[X]];
if(cnt[S]&1) return;
dp[S]=mod-dp[S];
}
inline void Fwt(int *f) {
for(re int i=2;i<=len;i<<=1)
for(re int ln=i>>1,l=0;l<len;l+=i)
for(re int x=l;x<l+ln;++x) {
f[x+ln]+=f[x];
if(f[x+ln]>=mod) f[x+ln]%=mod;
}
}
int main() {
n=read(),Q=read();X=read();
inv[1]=1;
for(re int i=2;i<=n;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(re int x,y,i=1;i<n;i++) {
x=read(),y=read(),d[x]++,d[y]++;
add(x,y),add(y,x);
}
len=(1<<n);
for(re int i=1;i<len;i++) cnt[i]=cnt[i>>1]+(i&1);
for(re int i=1;i<len;i++) solve(i);
Fwt(dp);
while(Q--) {
int k=read(),S=0;
for(re int i=1;i<=k;i++) S|=(1<<(read()-1));
printf("%d\n",dp[S]);
}
return 0;
}
我还是来补一下正解吧,据说这是树上随机游走的套路
我们设\(f_x\)表示从\(x\)到点集\(s\)的期望步数
据说树上路径唯一我们可以设\(f_x=A_xf_x+B_x\)
我们写出\(f_x\)的转移
\]
其中\(c\)是\(x\)的儿子
也就是
\]
\]
\]
于是我们现在解得
\]
\]
对于在\(S\)集合的点显然满足\(A=B=0\),叶子结点的\(A,B\)我们能直接算,我们一路推到根由于根没有父亲,所以\(f_{rt}=B_{rt}\),这样我们就能把所有的\(f_x\)都算出来了,复杂度是\(O(2^nn)\)
代码就不写了
「PKUWC2018」随机游走的更多相关文章
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- 「PKUWC2018」随机游走(min-max容斥+FWT)
「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...
- LOJ2542. 「PKUWC2018」随机游走
LOJ2542. 「PKUWC2018」随机游走 https://loj.ac/problem/2542 分析: 为了学习最值反演而做的这道题~ \(max{S}=\sum\limits_{T\sub ...
- LOJ #2542「PKUWC2018」随机游走
$ Min$-$Max$容斥真好用 $ PKUWC$滚粗后这题一直在$ todolist$里 今天才补掉..还要更加努力啊.. LOJ #2542 题意:给一棵不超过$ 18$个节点的树,$ 5000 ...
- loj2542「PKUWC2018」随机游走
题目描述 给定一棵 nn 个结点的树,你从点 xx 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 QQ 次询问,每次询问给定一个集合 SS,求如果从 xx 出发一直随机游走,直到点集 SS ...
- 【LOJ2542】「PKUWC2018」随机游走
题意 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一 ...
- loj#2542. 「PKUWC2018」随机游走(树形dp+Min-Max容斥)
传送门 首先,关于\(Min-Max\)容斥 设\(S\)为一个点的集合,每个点的权值为走到这个点的期望时间,则\(Max(S)\)即为走遍这个集合所有点的期望时间,\(Min(S)\)即为第一次走到 ...
- LOJ2542. 「PKUWC2018」随机游走【概率期望DP+Min-Max容斥(最值反演)】
题面 思路 我们可以把到每个点的期望步数算出来取max?但是直接算显然是不行的 那就可以用Min-Max来容斥一下 设\(g_{s}\)是从x到s中任意一个点的最小步数 设\(f_{s}\)是从x到s ...
- LOJ 2542 「PKUWC2018」随机游走 ——树上高斯消元(期望DP)+最值反演+fmt
题目:https://loj.ac/problem/2542 可以最值反演.注意 min 不是独立地算从根走到每个点的最小值,在点集里取 min ,而是整体来看,“从根开始走到点集中的任意一个点就停下 ...
随机推荐
- SpringBoot之Mybatis操作中使用Redis做缓存
上一博客学习了SpringBoot集成Redis,今天这篇博客学习下Mybatis操作中使用Redis做缓存.这里其实主要学习几个注解:@CachePut.@Cacheable.@CacheEvict ...
- python argparse(参数解析模块)
这是一个参数解析,可以用它快捷的为你的程序生成参数相关功能 import argparse(导入程序参数模块) # 创建argparse对象,并将产品简要说明加入show = '程序说明' ===&g ...
- SQL Server 数据类型映射(转载)
SQL Server 数据类型映射 SQL Server 和 .NET Framework 基于不同的类型系统. 例如,.NET Framework Decimal 结构的最大小数位数为 28,而 S ...
- [PHP]算法- 判断是否为二叉搜索树的后序遍历序列的PHP实现
二叉搜索树的后序遍历序列: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 思路: 1.后序遍历是 左右中 ...
- js之搜索框
目标效果:点击搜索框,搜索框内提示信息消失,可输入搜索信息,点击搜索框外搜索框如果没提示信息或者为空时,显示搜索框提示信息,如果有搜索信息,显示搜索信息. 代码如下: <!DOCTYPE htm ...
- BZOJ4259: 残缺的字符串(FFT 字符串匹配)
题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = ...
- HTML5是什么,以及优点和缺点
HTML5是超文本标记语言HTML的第五次重大修改 HTML 5 的第一份正式草案已于2008年1月22日公布 2013年5月6日, HTML 5.1正式草案公布 HTML5的优缺点是什么?作为HTM ...
- hosts 文件
各系统平台hosts文件存放路径 路径如下: Windows系统: C:\Windows\System32\drivers\etc\hosts Linux系统:/etc/hosts ...
- Windows 10修复
[以管理员运行如下命令]: 1.sfc /scannow 命令将扫描所有受保护的系统文件,并用位于 %WinDir%\System32\dllcache 的压缩文件夹中的缓存副本替换损坏的文件. 2. ...
- .Net Core(二)EFCore
EFCore与之前的EF基本类似,区别在于配置的时候有一些差异:也取消了DB First和Model First,仅保留广泛使用的Code First模式:也不再支持LazyLoad.这里就感受一下 ...