loj 2542 随机游走 —— 最值反演+树上期望DP+fmt

题目:https://loj.ac/problem/2542

因为走到所有点的期望就是所有点期望的最大值,所以先最值反演一下,问题变成从根走到一个点集任意一点就停止的期望值;

设 \( f[x] \),则 \( f[x] = \frac{f[fa]+1+\sum\limits_{v \in son} (f[v]+1)}{d[x]} \),其中 \( d[x] \) 是 \( x \) 的度数;

因为其实只和 \( fa \) 有关,所以套路是设 \( f[x] = K[x] * f[fa] + B[x] \),推一推就可以树形DP求 \( K[x] , B[x] \),这好像叫“树上高斯消元”?!

因为走到集合内任意一个点就停止,所以 \( K[x] = B[x] = 0 ( x \in S ) \),\( f[rt] \) 即 \( B[rt] \) 就是答案;

然后高维前缀和求子集的 \( f \) 和,注意最值反演的符号要一开始就带上。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int rd()
{
  int ret=0,f=1; char ch=getchar();
  while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=0; ch=getchar();}
  while(ch>=‘0‘&&ch<=‘9‘)ret=ret*10+ch-‘0‘,ch=getchar();
  return f?ret:-ret;
}
int const xn=20,xm=(1<<18)+5,mod=998244353;
int n,rt,sid[xn][xn],bin[xn],cnt[xm],K[xn],B[xn],d[xn],f[xm];
ll pw(ll a,int b){a%=mod; ll ret=1; for(;b;b>>=1,a=a*a%mod)if(b&1)ret=ret*a%mod; return ret;}
int upt(int x){while(x>=mod)x-=mod; while(x<0)x+=mod; return x;}
void dfs(int x,int fa,int s)
{
  if(s&bin[x-1]){K[x]=B[x]=0; return;}
  int ks=0,bs=0;
  for(int u=1;u<=n;u++)
    if(sid[x][u]&&u!=fa)
      dfs(u,x,s),ks=upt(ks+K[u]),bs=upt(bs+B[u]);
  K[x]=pw(d[x]-ks,mod-2); B[x]=(ll)(bs+d[x])*pw(d[x]-ks,mod-2)%mod;
}
int main()
{
  n=rd(); int Q=rd(); rt=rd();
  for(int i=1,x,y;i<n;i++)x=rd(),y=rd(),sid[x][y]=sid[y][x]=1,d[x]++,d[y]++;
  bin[0]=1; for(int i=1;i<=n;i++)bin[i]=(bin[i-1]<<1);
  for(int s=1;s<bin[n];s++)cnt[s]=cnt[s>>1]+(s&1);
  for(int s=1;s<bin[n];s++)
    {
      memset(K,0,sizeof K); memset(B,0,sizeof B);
      dfs(rt,0,s); f[s]=upt(((cnt[s]&1)?1:-1)*B[rt]);//
    }
  for(int i=1;i<=n;i++)
    for(int s=0;s<bin[n];s++)
      if(s&bin[i-1])f[s]=upt(f[s]+f[s^bin[i-1]]);
  for(int i=1,k,s;i<=Q;i++)
    {
      k=rd(); s=0;
      for(int j=1,x;j<=k;j++)x=rd(),s|=bin[x-1];
      printf("%d\n",f[s]);
    }
  return 0;
}

原文地址:https://www.cnblogs.com/Zinn/p/10279681.html

时间: 2024-11-12 09:17:01

loj 2542 随机游走 —— 最值反演+树上期望DP+fmt的相关文章

「Luogu4321」随机游走

「Luogu4321」随机游走 题目描述 有一张 \(n\) 个点 \(m\) 条边的无向图,\(Q\) 组询问,每次询问给出一个出发点和一个点集 \(S\) ,求从出发点出发随机游走走遍这个点集的期望步数. \(1 \leq n \leq 18, 1 \leq Q \leq 10^5\) 解题思路 : 听说是 \(\text{pkuwc2018d2t3}\) 加强版?但是原题时限是1s,各种卡不进去感觉一定要写 \(\text{Min-Max}\) 容斥,不过反正我今年听指导建议没报 \(\t

Loj #2542. 「PKUWC2018」随机游走

Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一直随机游走,直到点集 \(S\) 中所有点都至少经过一次的话,期望游走几步. 特别地,点 \(x\)(即起点)视为一开始就被经过了一次. 答案对 $998244353 $ 取模. 输入格式 第一行三个正整数 \(n,Q,x\). 接下来 \(

随机游走

在python中,可以利用数组操作来模拟随机游走. 下面是一个单一的200步随机游走的例子,从0开始,步长为1和-1,且以相等的概率出现.纯Python方式实现,使用了内建的 random 模块: # 随机游走 import matplotlib.pyplot as plt import random position = 0 walk = [position] steps = 200 for i in range(steps): step = 1 if random.randint(0, 1)

随机游走的matlab实现

<span style="font-family:KaiTi_GB2312;font-size:14px;">%随机游走产生图像效果实现,随机游走类似布朗运动,就是随机的向各个方向走</span> <span style="font-family:KaiTi_GB2312;font-size:14px;"><span style="color: rgb(68, 68, 68); line-height: 21px;

bzoj 3143 随机游走

题意: 给一个简单无向图,一个人从1号节点开始随机游走(即以相同概率走向与它相邻的点),走到n便停止,问每条边期望走的步数. 首先求出每个点期望走到的次数,每条边自然是从它的两个端点走来. 1 /************************************************************** 2 Problem: 3143 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:736 ms 7 Memory:

[PKUWC 2018]随机游走

Description 题库链接 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次询问给定一个集合 \(S\) ,求如果从 \(x\) 出发一直随机游走,直到点集 \(S\) 中所有点都至少经过一次的话,期望游走几步. 特别地,点 \(x\)(即起点)视为一开始就被经过了一次. 答案对 \(998244353\) 取模. Solution 不妨设 \(f_{i,S}\) 表示在点 \(i\) 时,要遍历集合

随机游走模型(RandomWalk Mobility)

随机游走模型由首先由爱因斯坦在1926年以数学方式描述.由于自然界中的许多实体会以不可预知的方式移动,因此随机游走模型用来描述这种不稳定的移动.在这种移动模型中,移动节点随机选择一个方向和速度来从当前位置移动到新的位置.新的速度和方向分别从预定义的范围[speedmin,speedmax]和[0,2].移动节点的每次移动会以恒定的时间间隔t或恒定的行进距离d进行,结束后会计算新的方向和速度.如果此模型的移动节点到达模拟边界,则它将从模拟边界"弹回",其角度有入射方向确定,然后沿着这条路

带黑洞的随机游走问题

对于无黑洞的随机游走问题可以使用线性方程组求解,对于有黑洞的随机游走问题就无法使用线性方程组进行求解了. 有黑洞的随机游走问题举例: 随机给定一个魔方状态,随机旋转期望通过多少步才能旋转到目标状态? 醉汉回家问题:一个人在x点处喝醉了,在N维空间中游走,它回到出发点的概率是多少?求p(N) zhihu 一个整型数字x=6000,每次增长101的概率为49.32%,每次减少100元的概率为50.68%,问最终x&tt;7000的概率是多少? 显然,这个问题相当于一个随机游走问题,一共有100~70

[BZOJ 3143][Hnoi2013]游走(高斯消元+期望)

Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. Solution 对于点u(u≠1):到达u的概率 f[u]=∑f[v]/d[v] (Edges(u,v)) 而f[1]=∑f[v]/d[v]+1