题意参见BZOJ3522

n<=100000

数据范围增强了,显然之前的转移方程不行了,那么不妨换一种。

因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方案数。

设f[i][j]表示i节点子树中与i距离为j的点的个数.

g[i][j]表示i节点子树中有g[i][j]对点满足每对点距离他们lca的距离都是d,他们lca距离i节点为d-j

也就是说现在已经找到两个节点了,需要再在没遍历的i的子树中找到一个距离i为j的点。

那么很容易得到转移方程:

ans+=f[x][j-1]*g[to[i]][j]

ans+=g[x][j+1]*f[to[i]][j]

g[x][j+1]+=f[to[i]][j]*f[x][j+1]

g[x][j-1]+=g[to[i]][j]

f[x][j+1]+=f[to[i]][j]

发现这个DP是合并深度信息转移的,而且子树信息被合并后就没用了,因此可以用长链剖分优化,每次继承重儿子信息,暴力合并其他子树。

因为父节点的f和g数组只由重儿子左移一位或右移一位得到,因此O(1)指针优化就好了。

具体应用到的长链剖分参见长链剖分

#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n;
int x,y;
int tot;
ll s[1000010];
int head[100010];
int to[200010];
int mx[100010];
int next[200010];
int son[100010];
int fa[100010];
ll ans;
ll *now=s+1;
ll *f[100010];
ll *g[100010];
void add(int x,int y)
{tot++;next[tot]=head[x];head[x]=tot;to[tot]=y;
}
void dfs(int x)
{mx[x]=0;for(int i=head[x];i;i=next[i]){if(to[i]!=fa[x]){fa[to[i]]=x;dfs(to[i]);mx[x]=max(mx[to[i]]+1,mx[x]);if(mx[to[i]]>mx[son[x]]){son[x]=to[i];}}}
}
void dfs2(int x)
{if(son[x]){f[son[x]]=f[x]+1;g[son[x]]=g[x]-1;dfs2(son[x]);}f[x][0]=1;ans+=g[x][0];for(int i=head[x];i;i=next[i]){if(to[i]!=fa[x]&&to[i]!=son[x]){f[to[i]]=now;now+=mx[to[i]]+1;g[to[i]]=now+mx[to[i]]+1;now+=mx[to[i]]*2+2;dfs2(to[i]);for(int j=mx[to[i]];j>=0;j--){if(j){ans+=f[x][j-1]*g[to[i]][j];}ans+=g[x][j+1]*f[to[i]][j];g[x][j+1]+=f[to[i]][j]*f[x][j+1];}for(int j=0;j<=mx[to[i]];j++){if(j){g[x][j-1]+=g[to[i]][j];}f[x][j+1]+=f[to[i]][j];}}}
}
int main()
{scanf("%d",&n);for(int i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}dfs(1);f[1]=now;now+=mx[1]+1;g[1]=now+mx[1]+1;now+=mx[1]*2+2;dfs2(1);printf("%lld",ans);
}

转载于:https://www.cnblogs.com/Khada-Jhin/p/9581559.html

BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP相关推荐

  1. 【BZOJ】4543: [POI2014]Hotel加强版-长链剖分DP

    传送门:bzoj4543 题解 三点两两距离相等的情况如下图: 设 f [ i ] [ j ] f[i][j] f[i][j]表示 i i i子树中与 i i i距离为 j j j(相对深度为 j j ...

  2. 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 ...

  3. bzoj4543. [POI2014]Hotel加强版

    bzoj4543. [POI2014]Hotel加强版 题面描述 Solution 先看n≤5e3n \leq 5e3n≤5e3怎么做. 考虑树形dpdpdp. 设f[i][j]f[i][j]f[i] ...

  4. 【luogu CF1009F】Dominant Indices(长链剖分优化DP)

    Dominant Indices 题目链接:luogu CF1009F 题目大意 给你一棵以 1 为根的树,设 d(u,x) 为 u 子树总到 u 距离为 x 的点数. 然后要你对于每个点 x 都要求 ...

  5. P3565 [POI2014]HOT-Hotels(树形dp+长链剖分)

    P3565 [POI2014]HOT-Hotels 参考题解 题目大意: 给定一棵树,在树上选 3 个点,要求两两距离相等,求方案数. 三个点树上两两距离为d存在下面两种情况 某个点三个子树(保证该点 ...

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

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

  7. 【BZOJ4543】Hotel加强版【神仙树形dp】【长链剖分】

    题意:给一棵 nnn 个点的树,求两两距离相等的三元组个数. n≤105n\leq 10^5n≤105 显然相当于是找一个点到这三个点距离相等.子树内和子树外到当前点的距离为某个值的点的个数可以长链剖 ...

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

    传送门 题意:求树上满足三点之间距离两两相等的三元组个数 n≤1e5n\le 1e5n≤1e5 原题数据是n≤5000n\le5000n≤5000 考虑怎么做 f[u][i]f[u][i]f[u][i ...

  9. 长链剖分优化树形dp

    apio铁牌告辞(开场想打暴力然后gedit码代码5个小时没写完三题最低档暴力真是快乐),听课也就学到了一丢丢这个东西. 模板题: https://www.luogu.org/problemnew/s ...

  10. 中心城镇问题(长链剖分优化树形dp)

    problem 给定 nnn 个城市,n−1n-1n−1 条道路,形成一棵树.每座城市上的人口为 wiw_iwi​. 现要修建若干个中心城镇,满足任意两个中心城镇之间的距离严格大于 kkk. 最大化中 ...

最新文章

  1. 原来matplotlib 散点图可以这样
  2. java settitle 源码_在其他初始化方法中折叠工具栏的setTitle - java代码 - 源码查
  3. iOS开发 Linker command fail with exit code 1(use -v to see invocation)
  4. Spark 云计算 ML 机器学习教程 以及 SPARK使用教程
  5. Div高度自适应内容高度
  6. 一文弄清传统软件开发与互联网软件开发的异同
  7. MATLAB 轮式机器人轨迹跟踪仿真
  8. “堆排序算法”(C语言实现)
  9. 微信APP支付-签名问题
  10. 70个python练手项目-一个不错的练手项目!
  11. Prometheus监控报警系统
  12. 手动获取我们所感兴趣网站X.509证书的一般方法
  13. 网络嗅探与欺骗----函数sniff()、ARP的原理、ARP欺骗、AARP欺骗的中间人攻击
  14. K8S污点taint的声明语法、污点的设置、查看和去除
  15. 模仿QQ背景为视频的登录页
  16. TCP/IP第四章笔记ARP协议
  17. Photon网络中Player中存取数据
  18. ACCESS数据库防下载方法
  19. Lua学习笔记(一)
  20. Internet 上可用的“简单网络时间协议”时间服务器列表

热门文章

  1. 除了iframe嵌套还有什么嵌套_嵌套了ROUND函数,为什么还会差1分钱,值得收藏
  2. android 结算权限,如何在Android应用程序中实施应用内结算?
  3. 玩家可以输入辅助指令_三菱FX系列PLC输入输出与辅助继电器之间有什么关系?...
  4. 将字符'0'-'9'转换为数字(c语言)
  5. c语言链表插入尾部,为什么我的程序一执行插入链表尾部,再执行别的操作就会出现问题,...
  6. python3 列表取交集_一刻钟学会 Python 3!Python不难学啊!
  7. 宝塔更换域名_搭建小程序之BT宝塔面板的操作使用教程
  8. Flutter实战1 --- 写一个天气查询的APP
  9. Fatal error: Uncaught Error: Call to undefined function gzinflate()
  10. oracle-pl/sql之二