题目

抄题解.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. [日常] nginx与location规则

    =========================================================================2018年3月28日 记录: location = / ...

  2. Hibernate中一级缓存概念以及flush与clear的区别

    Hibernate采用缓存机制提高数据查询效率.缓存分为一级缓存和二级缓存,一级缓存在Session中存在,二级缓存需要手动配置. 在一级缓存中,如果数据保存到数据库中后,而session又没有关闭的 ...

  3. mysql中的坑

    1,MySQL建表中double类型不能限制数据长度! 2,……

  4. J2EE企业级应用架构发展

    一. 准备工作 1. 本文参考 J2EE企业级应用架构 二. 架构发展 1. 原始版 用户+服务器[单台虚拟机]+数据库[mysql或者oracle],用户访问量比较少. 特点:单节点[只有一台机器] ...

  5. php excel原理

  6. UOJ#328. 【UTR #3】量子破碎

    传送门 学过 \(FWT\) 看到操作 \(2\) 不难可以联想到 \(FWT\) 考虑一遍 \(\oplus\) \(FWT\) 会把 \(a_t\) 变成什么 \(a_t'=((-1)^{bitc ...

  7. 好用的js-cookies工具

    背景 回顾一年前的代码,关于cookies这块,增删改查完全可以封装成一个模块.在MDN上看到一款很全的分享,在此做个记录. cookies模块 /*\ |*| |*| :: cookies.js : ...

  8. opencv图像处理基础 (《OpenCV编程入门--毛星云》学习笔记一---五章)

    #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgu ...

  9. Automate the Sizing of your SGA in Oracle 10g

    How much memory does each of the individual components of the SGA need? Oracle now has methods to de ...

  10. Ubuntu16安装GPU版本TensorFlow(个人笔记本电脑)

    想着开始学习tf了怎么能不用GPU,网上查了一下发现GeForce GTX确实支持GPU运算,所以就尝试部署了一下,在这里记录一下,避免大家少走弯路. 使用个人笔记本电脑thinkpadE570,内存 ...