魏佬怒嘲我只会做给定一棵树,输出有多少个点这种问题

不过我连这个也不会做

还算一道不错的树上数数题目

但是我一直不会数数

求树上所有的三元组\((u,v,t)\),满足\(dis(u,v)=dis(u,t)=dis(v,t)\)的个数

感觉好神仙啊,一眼不会的感觉

之后试着挖掘一下性质,发现只要我们需要找一个点\(x\)使得这三个点到\(dis(x,u)=dis(x,v)=dis(x,t)\)好像就可以了

吗?

显然不行啊

就比如这一棵树,确实这里是有\(dis(x,u)=dis(v,x)=dis(t,x)=2\),但是\(dis(u,v)=2\),而\(dis(t,u)=4\),这显然并不对

所以这个性质还得有一个限制条件,就是\(x=LCA(u,v)\)

我们把问题分成两步

  1. \(u,v,t\)在一棵子树里

  2. \(u,v\)在一棵子树里,\(t\)在子树外

有没有\(up\ and\ down\)的意味了,在\(up\)里我们就能统计第一种情况的答案了

我们定义\(dp[x][j]\)表示在\(x\)的子树内部有多少个点到达\(x\)的距离为\(j\),显然这个非常好转移

\(f[x][j]\)表示在\(x\)的子树内部,有多少对\((u,v)\)满足\(dis(u,v)=j\),且\(LCA(u,v)=x\),这个在合并子树的时候也可顺边求出来

而合并子树的时候,我们每次合并的时候就可以统计第一种答案了,由于\(u\)和\(v\)显然不能来自于同一棵子树内部,所以合并的时候直接拿这个去乘上之前的\(f[x][j]\)就好了

第二种情况,我们直接\(down\)下来,首先还是先\(down\)一下\(dp\)数组,求出子树外部到\(x\)距离为\(j\)的点有多少个,这些点就可以作为\(t\),之后乘上\((u,v)\)点对的数量,我们就可以把答案合并出来了

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define maxn 5001
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
struct E
{
short v,nxt;
}e[maxn<<1];
short deep[maxn],head[maxn],md[maxn];
int dp[maxn][maxn],f[maxn][maxn];
int n,num;
LL ans;
inline void add_edge(int x,int y)
{
e[++num].v=y;
e[num].nxt=head[x];
head[x]=num;
}
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;
}
inline LL merge(LL x,LL y)
{
return (x-1)*x/2*y;
}
void dfs(int x)
{
dp[x][0]++;
for(re int i=head[x];i;i=e[i].nxt)
if(!deep[e[i].v])
{
md[e[i].v]=deep[e[i].v]=deep[x]+1;
dfs(e[i].v);
md[x]=max(md[x],md[e[i].v]);
for(re int j=1;j<=md[x];j++)
ans+=f[x][j]*dp[e[i].v][j-1],f[x][j]+=dp[x][j]*dp[e[i].v][j-1],dp[x][j]+=dp[e[i].v][j-1];
}
}
void Redfs(int x)
{
for(re int i=head[x];i;i=e[i].nxt)
if(deep[e[i].v]>deep[x])
{
for(re int j=n;j;j--)
if(j>=2) ans+=(dp[x][j-1]-dp[e[i].v][j-2])*f[e[i].v][j],dp[e[i].v][j]+=dp[x][j-1]-dp[e[i].v][j-2];
else ans+=dp[x][j-1]*f[e[i].v][j],dp[e[i].v][j]+=dp[x][j-1];
Redfs(e[i].v);
}
}
int main()
{
n=read();
int x,y;
for(re int i=1;i<n;i++)
x=read(),y=read(),add_edge(x,y),add_edge(y,x);
md[1]=deep[1]=1;
dfs(1);
Redfs(1);
std::cout<<ans;
return 0;
}

【[POI2014]HOT-Hotels】的更多相关文章

  1. 【BZOJ】【3522】【POI2014】Hotel

    暴力/树形DP 要求在树上找出等距三点,求方案数,那么用类似Free Tour2那样的合并方法,可以写出: f[i][j]表示以 i 为根的子树中,距离 i 为 j 的点有多少个: g[i][j]表示 ...

  2. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  3. 【夯实PHP基础】PHP数组,字符串,对象等基础面面观

    本文地址 分享提纲 1.数组篇 2.字符创篇 3.函数篇 4.面向对象篇 5.其他篇 /*************************** 一.数组篇 Begin***************** ...

  4. 【Java学习系列】第3课--Java 高级教程

    本文地址 可以拜读: 从零开始学 Java 分享提纲: 1. Java数据结构 2. Java 集合框架 3. Java泛型 4. Java序列化 5. Java网络编程 6. Java发送Email ...

  5. 【夯实PHP基础】nginx php-fpm 输出php错误日志

    本文地址 原文地址 分享提纲: 1.概述 2.解决办法(解决nginx下php-fpm不记录php错误日志) 1. 概述 nginx是一个web服务器,因此nginx的access日志只有对访问页面的 ...

  6. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  7. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  8. 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  9. 【初码干货】在Window Server 2016中使用Web Deploy方式发布.NET Web应用的重新梳理

    在学习和工作的过程中,发现很多同事.朋友,在做.NET Web应用发布的时候,依然在走 生成-复制到服务器 这样的方式,稍微高级一点的,就是先发布到本地,再上传到服务器 这种方式不仅效率低下,而且不易 ...

  10. 【夯实PHP基础】PHP的反射机制

    本文地址 分享提纲: 1. 介绍 2. 具体例子 2.1 创建Persion类 2.2 反射过程 2.3 反射后使用 1. 介绍 -- PHP5添加了一项新的功能:Reflection.这个功能使得p ...

随机推荐

  1. 15、IO (转换流、缓冲流)

    转换流概述 * A: 转换流概述 * a: 转换流概述 * OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节 * 将字符串按照指定的 ...

  2. C#实现局部峰值查找,功能对应Matlab中的findpeaks.m

    相关算法的原理参考Ronny,地址:图像分析:投影曲线的波峰查找,这里感谢下原作者. 参照C++的代码实现,我用C#翻译了下,其实原理也很简单的,下面放相关实现代码: private double[] ...

  3. CSS知多少

    1.Cascading Style Sheets 层叠样式表 2.层叠就是浏览器对多个样式来源进行叠加,最终确定结果的过程. 3. 样式的5大来源:浏览器默认样式.浏览器用户自定义样式.行内样式.内部 ...

  4. 初级篇html。

    什么是html?  超文本标记语言,标准通用标记语言下的一个应用. “超文本”就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 超文本标记语言的结构包括“头”部分(英语:Head).和“主 ...

  5. LintCode2016年8月22日算法比赛----将数组重新排序以构造最小值

    将数组重新排序以构造最小值 题目描述 给定一个整数数组,请将其重新排序,以构造最小值. 样例 给定[3,32,321],通过将数组重新排序,可构造6个可能性的数字: 3+32+321=332321 3 ...

  6. Benefits of encapsulation

    ①:通过方法来控制成员变量的操作,提高了代码的安全性. ②:把代码用方法进行封装,提高了代码的复用性.

  7. Android 虚拟多开系列一——技术调研

    参考链接:http://weishu.me Github源码链接:             国内Xposed框架源码链接                               VirtualAp ...

  8. Bitmap到底占多少内存

    转至:Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存? Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟 ...

  9. 养兔子Fibo函数优化

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 剑指offer相关问题

    1. 变态跳台阶 Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+..........+Fib(n-n)         =Fib(0)+Fib(1)+Fib(2)+..... ...