题目

抄题解.jpg

发现原来的\(O(n^2)\)的换根\(dp\)好像行不通了呀

我们考虑非常牛逼的长链剖分

我们设\(f[x][j]\)表示在\(x\)的子树中距离\(x\)为\(j\)的点有多少个

\(g[x][j]\)表示在\(x\)的子树里,满足如下条件的点对\((u,v)\)的个数

  1. 设\(k=LCA(u,v)\),满足\(dis(u,k)=dis(v,k)=d\)

  2. 满足\(dis(k,x)=d-j\)

我们发现可以如果\(v\)是\(x\)的儿子,那么距离\(v\)为\(j-1\)的点和\(x\)的距离就是\(j\),那么到\(k\)的距离就是\(d-j+j=d\),和点对到\(k\)的距离相等

于是我们可以这样合并

\[ans+=f[v][j-1]\times g[x][j]
\]

自然还有

\[ans+=f[x][j-1]\times g[v][j]
\]

\(f\)数组的更新非常简单啊,就是\(f[x][j]+=f[v][j-1]\),这个我们可以用长链剖分优化到\(O(n)\)

之后是\(g\)的更新

首先我们有\(g[x][j]+=g[v][j+1]\),就是到\(x\)距离为\(d-j\)的\(k\)到\(v\)的距离必然是\(d-j-1\),这里我们也可以直接长链剖分

之后\(g[x][j+1]+=f[x][j+1]\times f[v][j]\),这样产生的点对的\(LCA\)就是\(x\),到\(x\)的距离也就是\(j+1\),符合条件,这里直接暴力转移就好了

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=100006;
inline int read() {
char c=getchar();int x=0;while(c<'0'||x>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt;}e[maxn<<1];
int head[maxn],len[maxn],n,num,son[maxn],deep[maxn];
LL tax[maxn*6],*id=tax,*f[maxn],*g[maxn],ans;
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
void dfs1(int x) {
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
deep[e[i].v]=deep[x]+1;
dfs1(e[i].v);
if(len[e[i].v]>len[son[x]]) son[x]=e[i].v;
}
len[x]=len[son[x]]+1;
}
void dfs(int x) {
f[x][0]=1;
if(son[x]) {
g[son[x]]=g[x]-1;
f[son[x]]=f[x]+1;
dfs(son[x]);
}
ans+=g[x][0];
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]<deep[x]||son[x]==e[i].v) continue;
f[e[i].v]=id;id+=len[e[i].v]+1;
g[e[i].v]=id+len[e[i].v]+1;id+=2*len[e[i].v]+2;
dfs(e[i].v);
for(re int j=len[e[i].v];j>=0;--j) {
if(j) ans+=f[x][j-1]*g[e[i].v][j];
ans+=g[x][j+1]*f[e[i].v][j];
g[x][j+1]+=f[e[i].v][j]*f[x][j+1];
}
for(re int j=0;j<=len[e[i].v];j++) {
if(j) g[x][j-1]+=g[e[i].v][j];
f[x][j+1]+=f[e[i].v][j];
}
}
}
int main() {
n=read();
for(re int x,y,i=1;i<n;i++)
x=read(),y=read(),add(x,y),add(y,x);
deep[1]=1;dfs1(1);
f[1]=id;id+=len[1]+1;
g[1]=id+len[1]+1;//由于我们继承重儿子是g[son[x]]=g[x]-1,所以得在这个指针前面留一些空位置来让后面的状态继承
id+=2*len[1]+2;
dfs(1);printf("%lld\n",ans);
return 0;
}

【bzoj4543】[POI2014]Hotel加强版的更多相关文章

  1. BZOJ4543 POI2014 Hotel加强版 【长链剖分】【DP】*

    BZOJ4543 POI2014 Hotel加强版 Description 同OJ3522 数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 4 ...

  2. BZOJ4543 [POI2014]Hotel加强版

    题意 有一个树形结构,每条边的长度相同,任意两个节点可以相互到达.选3个点.两两距离相等.有多少种方案? 数据范围:n<=100000 分析 参照小蒟蒻yyb的博客. 我们先考虑一个\(O(n^ ...

  3. bzoj4543 [POI2014]Hotel加强版 长链剖分+树形DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4543 题解 这道题的弱化版 bzoj3522 [POI2014]Hotel 的做法有好几种吧. ...

  4. BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP

    题意参见BZOJ3522 n<=100000 数据范围增强了,显然之前的转移方程不行了,那么不妨换一种. 因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方 ...

  5. 2019.01.08 bzoj4543: [POI2014]Hotel加强版(长链剖分+dp)

    传送门 代码: 长链剖分好题. 题意:给你一棵树,问树上选三个互不相同的节点,使得这个三个点两两之间距离相等的方案数. 思路: 先考虑dpdpdp. fi,jf_{i,j}fi,j​表示iii子树中离 ...

  6. 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP

    [BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...

  7. 【BZOJ4543】Hotel加强版(长链剖分)

    [BZOJ4543]Hotel加强版(长链剖分) 题面 BZOJ,没有题面 洛谷,只是普通版本 题解 原来我们的\(O(n^2)\)做法是设\(f[i][j]\)表示以\(i\)为根的子树中,距离\( ...

  8. 4543: [POI2014]Hotel加强版

    4543: [POI2014]Hotel加强版 链接 分析: f[u][i]表示子树u内,距离u为i的点的个数,g[u][i]表示在子树u内,已经选了两个深度一样的点,还需要在距离u为i的一个点作为第 ...

  9. 【BZOJ4543】Hotel加强版

    [BZOJ4543]Hotel加强版 题面 bzoj 洛谷 $ps:$在洛谷看题在bzoj交... 题解 我们分析一下这个问题,要怎么样的点才满足三点距离两两相等呢? 1.存在三个点有共同的$LCA$ ...

  10. bzoj4543[POI2014]Hotel

    题目链接 bzoj4543 [POI2014]Hotel 题解 这不是裸地点分嘛 ,我真傻,真的 n^2 这不是是sb题,~滑稽 ~ 枚举点转换为无根树,暴力子树中点的深度 计数转移 令a b c d ...

随机推荐

  1. 2017年10月21日 CSS常用样式&鼠标样式 以及 jQuery鼠标事件& jQuery图片轮播& jQuery图片自动轮播代码

    css代码 背景与前景 background-color:#0000; //背景色,样式表优先级高 background-image:url(路径); //设置背景图片 background-atta ...

  2. Linux线程同步——条件变量

    互斥锁是用来给资源上锁的,而条件变量是用来等待而不是用来上锁的. 条件变量用来自动阻塞一个线程,直到某特殊情况发生为止. 通常条件变量和互斥锁同时使用. 和条件变量使用有关的几个重要函数: int p ...

  3. 如何优雅的爬取 gzip 格式的页面并保存在本地(java实现)

    1. 引言 在爬取汽车销量数据时需要爬取 html 保存在本地后再做分析,由于一些页面的 gzip 编码格式, 获取后要先解压缩,否则看到的是一片乱码.在网络上仔细搜索了下,终于在这里找到了一个优雅的 ...

  4. “使用IDEA,配置文件是yml,无法获取[环境变量],值是null”的问题处理

    为了便于隐藏用户名和密码,我们有时会用到“环境变量”. Spring Boot提供了很好的机制,可以在配置文件中,如application.yml书写以下格式,然后在代码中@Value就可以获取“环境 ...

  5. 微信开发e.target.dataset取值undefined

    替换为: e.currentTarget.dataset.current

  6. Vue2.x之父子组件数据传递

    父传子,并且通过fatherEvent接收子组件传过来的值 <template> <div class='father'> <Son :fatherData=" ...

  7. linux系统下开启一个简单的web服务

    linux 下开启一个简单的web服务: 首先需要linux下安装nodejs 然后创建一个test.js:   vi test.js var http =require("http&quo ...

  8. MPVUE - 使用vue.js开发微信小程序

    MPVUE - 使用vue.js开发微信小程序 什么是mpvue? mpvue 是美团点评前端团队开源的一款使用 Vue.js 开发微信小程序的前端框架.框架提供了完整的 Vue.js 开发体验,开发 ...

  9. h5笔记

    标签 更语义化标签 header标签 nav标签 section标签 article标签 aside标签 widget标签 footer标签 为什么要有语义化标签 能够便于开发者阅读和写出更优雅的代码 ...

  10. Evernote Markdown Sublime使用介绍

    版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4002619.html 这一篇博客继续探讨:Evernote ...