(警告:本篇博客包含大量人类本质内容)

先处理出来lca,然后就只需要知道从每个点到他的父亲、和从他的父亲到这个点的期望时间就可以了

我们设f[x]为x到他父亲的期望时间;g[x]为从x的父亲到x的期望时间(注意到这两个是不一样的)

只考虑怎么算f,g是类似的

从某个点想走到他父亲时,情况会有:直接走到;先走到某个儿子然后走回来,再走到父亲;先走到某个儿子然后走回来,再走到某个儿子然后走回来,再走到某个儿子然后走回来,....,然后走到父亲

假设x有k个儿子,每个儿子记为ch[1...k]

那我们能得出$f[x]=\frac{1}{k+1}+\sum\limits_{i=1}^{k}{\frac{f[ch[i]]+1}{k+1}}+\frac{k}{k+1}(\frac{1}{k+1}+\sum\limits_{i=1}^{k}{\frac{f[ch[i]]+1}{k+1}}+\frac{k}{k+1}(...$

意思是,有$\frac{1}{k+1}$的可能性直接走到,另外$\frac{1}{k+1}$先用1时间走错到儿子、然后再用儿子的那个期望时间走回来,并以$\frac{k}{k+1}$的可能性再次有$\frac{1}{k+1}$的可能性直接走到,另外$\frac{1}{k+1}$先用1时间走错到儿子、然后再用儿子的那个期望时间走回来,并以$\frac{k}{k+1}$的可能性再次...

把$\frac{1}{k+1}+\sum\limits_{i=1}^{k}{\frac{f[ch[i]]+1}{k+1}}$记为a,$\frac{k}{k+1}$,就有$f[x]=a+b(a+b(a+b(a+b(....=(1+b^1+b^2+...)a=\frac{a}{1-b}$(等比数列和的极限)

这样dfs一下(好几下),就可以算出f了,g同理(注意顺序,两次dfs分别算f和g,算f的时候先算孩子,算g的时候先算父亲),只不过是有可能走错到父亲

然后倍增记一记f和g的和,做lca就行了(注意路径的方向)

然后就wa了...

可以发现其实这些期望都是整数,因为$\frac{1}{1-b}=k+1$,而a的分母又都是k+1...所以改用long long,避免掉奇奇怪怪的精度问题,就可以过了..(怀疑是%.4lf是否四舍五入的问题,我的本地是会四舍五入的所以拍不出锅,但要是直接截取就锅了...)

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=5e4+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int eg[maxn*][],egh[maxn],ect;
int N,Q;
ll f[maxn][],g[maxn][];
int fa[maxn][],dep[maxn]; inline void adeg(int a,int b){
eg[++ect][]=b;eg[ect][]=egh[a];egh[a]=ect;
} void dfs1(int x){
int k=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
dep[b]=dep[x]+;fa[b][]=x;
k++;dfs1(b);
}
if(fa[x][]){
ll alpha=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
alpha+=f[b][]+;
}
f[x][]=alpha;
} } void dfs2(int x){
int k=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
k++;
}
if(fa[x][]){
ll alpha=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
alpha+=f[b][]+;
}
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
ll alphai=alpha-(f[b][]+);
alphai+=g[x][]+;
g[b][]=alphai;
}
}else{
ll alpha=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
alpha+=f[b][]+;
}
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
double alphai=alpha-(f[b][]+);
g[b][]=alphai;
}
}
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
dfs2(b);
}
// printf("%d %lf %lf\n",x,f[x][0],g[x][0]);
} void getst(int x){
for(int i=;fa[x][i]&&fa[fa[x][i]][i];i++){
fa[x][i+]=fa[fa[x][i]][i];
f[x][i+]=f[x][i]+f[fa[x][i]][i];
g[x][i+]=g[x][i]+g[fa[x][i]][i];
// printf("%d %d %d %lf %lf\n",x,i+1,fa[x][i+1],f[x][i+1],g[x][i+1]);
}
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
getst(b);
}
} inline ll solve(int s,int t){
ll re=;
if(dep[s]>dep[t]){
for(int i=;i>=;i--){
if(fa[s][i]&&dep[fa[s][i]]>=dep[t]){
re+=f[s][i],s=fa[s][i];
}
}
// if(s==t) return re-f[s][0];
}else if(dep[t]>dep[s]){
for(int i=;i>=;i--){
if(fa[t][i]&&dep[fa[t][i]]>=dep[s]){
re+=g[t][i],t=fa[t][i];
}
}
// if(s==t) return re-g[t][0];
}
if(s==t) return re;
for(int i=;i>=;i--){
if(fa[s][i]&&fa[t][i]&&fa[s][i]!=fa[t][i]){
re+=f[s][i]+g[t][i];
s=fa[s][i],t=fa[t][i];
}
}re+=f[s][]+g[t][];
return re;
} int main(){
// freopen("5449.in","r",stdin);
// freopen("5449.out","w",stdout);
int i,j,k;
for(int T=rd();T;T--){
CLR(fa,);CLR(dep,);CLR(egh,);ect=;
CLR(f,);CLR(g,);
N=rd();
for(i=;i<N;i++){
int a=rd()+,b=rd()+;
adeg(a,b);adeg(b,a);
}
dep[]=;dfs1();dfs2();
getst();
Q=rd();
for(i=;i<=Q;i++){
int p=rd(),lst=rd()+;
ll ans=;
for(j=;j<=p;j++){
int now=rd()+;
ans+=solve(lst,now);
lst=now;
}
printf("%lld.0000\n",ans);
}
if(T>) printf("\n");
}
return ;
}

hdu5449 Robot Dog (树形dp+倍增lca)的更多相关文章

  1. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  2. 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...

  3. [NOIP2018]保卫王国(树形dp+倍增)

    我的倍增解法吊打动态 \(dp\) 全局平衡二叉树没学过 先讲 \(NOIP\) 范围内的倍增解法. 我们先考虑只有一个点取/不取怎么做. \(f[x][0/1]\) 表示取/不取 \(x\) 后,\ ...

  4. hdu 4123(树形dp+倍增)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. 青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

    题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 ...

  6. P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp

    题目:给出n个点的树  q次询问  问切断 k个点(不和1号点联通)的最小代价是多少 思路:树形dp  sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权 ...

  7. 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1231  Solved: 620[Submit][Stat ...

  8. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  9. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

随机推荐

  1. 大数据入门第十二天——flume入门

    一.概述 1.什么是flume 官网的介绍:http://flume.apache.org/ Flume is a distributed, reliable, and available servi ...

  2. 20155306 白皎 0day漏洞——漏洞利用原理之DEP

    20155306 白皎 0day漏洞--漏洞利用原理之DEP 一.DEP机制的保护原理 1.为什么出现DEP? 溢出攻击的根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计 ...

  3. SQL面试整理(1)——数据库连接池

    在web开发中,如果JSP.Servlet或EJB使用JDBC直接访问数据库,每一次数据访问请求都必须经历建立数据库连接,打开数据库,存取数据库和关闭数据库连接等操作步骤,如果频繁发生这种数据库操作, ...

  4. HDU 6333 Harvest of Apples (分块、数论)

    题目连接:Harvest of Apples 题意:给出一个n和m,求C(0,n)+C(1,n)+.....+C(m,n).(样例组数为1e5) 题解:首先先把阶乘和逆元预处理出来,这样就可O(1)将 ...

  5. 使用 idea 的Bookmarks(书签)功能

    https://blog.csdn.net/qq_36376059/article/details/80277767

  6. WinForm 随手记

    从今天开始咱们正式进入WinForm开发模式 首先很官方的介绍下什么是winform:客户端应用程序:C/S 这就是winform 有什么特别特别重要的特点呢:可以操作用户电脑上的文件 举个简单的例子 ...

  7. JavaScript中执行环境和栈

    在这篇文章中,我会深入理解JavaScript最根本的组成之一 : "执行环境(执行上下文)".文章结束后,你应该对解释器试图做什么,为什么一些函数/变量在未声明时就可以调用并且他 ...

  8. page = new String(request.getQueryString().getBytes("ISO-8859-1"),"GBK");解决前台传后台乱码问题

    page = new String(request.getQueryString().getBytes("ISO-8859-1"),"GBK");解决前台传后台 ...

  9. LeetCode 633. 平方数之和

    题目: 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c.     示例1: 输入: 5 输出: True 解释: 1 * 1 + 2 * 2 = 5 示例2 ...

  10. 第二个spring冲刺第9天

    其中一个队员在检查程序的BUG途中发现了几个重要的BUG比如答案乱码.程序闪退,弹出黑幕.于是我们决定先把这些问题解决再继续开发其他功能