题目大意

​  给你一棵树,求有多少个组点满足\(x\neq y,x\neq z,y\neq z,dist_{x,y}=dist_{x,z}=dist_{y,z}\)

​  \(1\leq n\leq 100000\)

题解

​  问题转换为有多少个组点满足\(dist_{i,x}=dist_{i,y}=dist_{i,z}\)

​  我们考虑树形DP

​  \(f_{i,j}=\)以\(i\)为根的子树中与\(i\)的距离为\(j\)的节点数

​  \(g_{i,j}=\)以\(i\)为根的子树外选择一个点\(s\)满足\(s\)到\(i\)的距离为\(j\),能新增的的方案数

​  若\(v\)是\(u\)的重儿子,则:\(f_{u,j}+=f_{v,j-1},g_{u,j}+=g_{v,j+1}\),这样就可以由\(u\)的重儿子转移到\(u\)

​  否则:\(g_{u,j}+=g_{v,{j+1}}+f_{v,j-1}\times f_{u,j},f_{u,j}+=f_{v,j-1}\)

​  答案为\(\sum f_{x,j}\times g_{y,j}\),其中\(x\)是\(y\)的兄弟

​  可以用长链剖分辅助转移

​  时间复杂度:\(O(n)\)

​  gjs大爷的长链剖分讲解

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
struct list
{
int v[200010];
int t[200010];
int h[100010];
int n;
void clear()
{
n=0;
memset(h,0,sizeof h);
}
void add(int x,int y)
{
n++;
v[n]=y;
t[n]=h[x];
h[x]=n;
}
};
list l;
ll ans;
ll f[100010];
ll g[200010];
int d[100010];
int bg[100010];
int ed[100010];
int ch[100010];
int t[100010];
int w[100010];
int ti;
void dfs(int x,int fa)
{
d[x]=1;
ch[x]=0;
int i;
for(i=l.h[x];i;i=l.t[i])
if(l.v[i]!=fa)
{
dfs(l.v[i],x);
if(d[l.v[i]]+1>d[x])
{
d[x]=d[l.v[i]]+1;
ch[x]=l.v[i];
}
}
}
void dfs2(int x,int fa,int top)
{
t[x]=top;
w[x]=++ti;
if(x==top)
bg[top]=ti;
ed[top]=ti;
if(ch[x])
dfs2(ch[x],x,top);
int i;
for(i=l.h[x];i;i=l.t[i])
if(l.v[i]!=ch[x]&&l.v[i]!=fa)
dfs2(l.v[i],x,l.v[i]);
}
ll& getf(int x,int y)
{
return f[w[x]+y];
}
ll& getg(int x,int y)
{
return g[2*(w[t[x]]-1)+2*d[t[x]]-d[x]+1-y];
}
void solve(int x,int fa)
{
if(ch[x])
solve(ch[x],x);
int i,j;
for(i=l.h[x];i;i=l.t[i])
if(l.v[i]!=fa&&l.v[i]!=ch[x])
{
int v=l.v[i];
solve(v,x);
for(j=0;j<d[v];j++)
ans+=getf(v,j)*getg(x,j+1);
for(j=1;j<d[v];j++)
ans+=getg(v,j)*getf(x,j-1);
for(j=0;j<d[v];j++)
getg(x,j+1)+=getf(v,j)*getf(x,j+1);
for(j=1;j<d[v];j++)
getg(x,j-1)+=getg(v,j);
for(j=0;j<d[v];j++)
getf(x,j+1)+=getf(v,j);
}
ans+=getg(x,0);
getf(x,0)++;
}
int main()
{
int n;
scanf("%d",&n);
l.clear();
memset(bg,0,sizeof bg);
memset(ed,0,sizeof ed);
memset(f,0,sizeof f);
memset(g,0,sizeof g);
memset(d,0,sizeof d);
memset(ch,0,sizeof ch);
memset(t,0,sizeof t);
memset(w,0,sizeof w);
ans=0;
ti=0;
int i,x,y;
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
l.add(x,y);
l.add(y,x);
}
dfs(1,0);
dfs2(1,0,1);
solve(1,0);
printf("%lld\n",ans);
return 0;
}

【BZOJ3522】【BZOJ4543】【POI2014】Hotel 树形DP 长链剖分 启发式合并的更多相关文章

  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. 2019.01.08 bzoj4543: [POI2014]Hotel加强版(长链剖分+dp)

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

  3. 【BZOJ3522&BZOJ4543】Hotel加强版(长链剖分,树形DP)

    题意:求一颗树上三点距离两两相等的三元组对数 n<=1e5 思路:From https://blog.bill.moe/bzoj4543-hotel/ f[i][j]表示以i为根的子树中距离i为 ...

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

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

  5. BZOJ4543/BZOJ3522 [POI2014]Hotel加强版(长链剖分)

    题目好神仙--这个叫长链剖分的玩意儿更神仙-- 考虑dp,设\(f[i][j]\)表示以\(i\)为根的子树中到\(i\)的距离为\(j\)的点的个数,\(g[i][j]\)表示\(i\)的子树中有\ ...

  6. 【BZOJ3522】[Poi2014]Hotel 树形DP

    [BZOJ3522][Poi2014]Hotel Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房 ...

  7. [2016北京集训试题7]thr-[树形dp+树链剖分+启发式合并]

    Description Solution 神仙操作orz. 首先看数据范围,显然不可能是O(n2)的.(即绝对不是枚举那么简单的),我们考虑dp. 定义f(x,k)为以x为根的子树中与x距离为k的节点 ...

  8. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  9. [bzoj3522][bzoj4543][POI2014]HOTEL

    题解: 比较难的一道题目 首先考虑暴力dp 我们会发现构成这种形状只有三种情况 1.三个点的lca相同 2.两个点lca相同,第三个点是lca的祖先 3.两个点lca相同,第三个点是lca祖先的子树中 ...

随机推荐

  1. 动态规划-LCS最长公共子序列

    #include<iostream> #include<cstdio> #include<cstring> #include<string> using ...

  2. python 的内存回收,及深浅Copy详解

    一.python中的变量及引用 1.1 python中的不可变类型: 数字(num).字符串(str).元组(tuple).布尔值(bool<True,False>) 接下来我们讲完后你就 ...

  3. WebSocket实现一个聊天室

    聊天室页面-->index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8&q ...

  4. alibaba druid

    FAQ · alibaba/druid Wikihttps://github.com/alibaba/druid/wiki/FAQ sql 连接数不释放 ,Druid异常:wait millis 40 ...

  5. mysql之找回误删数据

    场景:我们开发阶段,经常要有一些测试数据在我们测试相关功能的时候,是十分必要的.后期由于引入了正式的数据,但是测试数据并没有被及时清理.这个时候由于一个误删除,导致一些正式的数据被删除,由此,一场追找 ...

  6. react-router的坑

    componentWillReceiveProps(nextProps){ 在改钩子函数里接受组件变化的最近的传递的props 如果在这里没有使用nextprops 而是调用this.props 会出 ...

  7. MySQL 日期类型函数及使用

    1 MySQL 数据库中有五种与日期时间有关的数据类型,各种日期数据类型所占空间如下图所示: 2 datetime 与 date datetime 占用8字节,是占用空间最多的一种日期格式.它显示日期 ...

  8. linux关闭触摸板

    关闭触摸板 sudo modprobe -r psmouse 如果打开触摸板就是: sudo modprobe psmouse

  9. UTF-8编码与GBK编码下的字符长度

    源码: package lsh.java.charset; import java.nio.charset.Charset; public class LengthOfUTF_8 { public s ...

  10. MySQL中KEY、PRIMARY KEY、UNIQUE KEY、INDEX 的区别

    参考:MySQL中KEY.PRIMARY KEY.UNIQUE KEY.INDEX 的区别 对于题目中提出的问题,可以拆分来一步步解决.在 MySQL 中 KEY 和 INDEX 是同义.那这个问题就 ...