BZOJ4543/BZOJ3522 [POI2014]Hotel加强版(长链剖分)
题目好神仙……这个叫长链剖分的玩意儿更神仙……
考虑dp,设\(f[i][j]\)表示以\(i\)为根的子树中到\(i\)的距离为\(j\)的点的个数,\(g[i][j]\)表示\(i\)的子树中有\(g[i][j]\)对点深度相同,他们到LCA的距离为\(d\),且他们的LCA到\(i\)的距离为\(d-j\)。或者换句话来说就是以\(i\)为根的子树中有这么多个点对,而且没有第三个点去和这些点对匹配,第三个点不在\(i\)的子树中且到\(i\)的距离为\(j\),\(g[i][j]\)表示这些点对的个数
设\(u\)为当前点,\(v\)为某一子树,那么转移方程如下
\]
\]
\]
\]
如果是原题的\(n\leq 5000\)已经足够了,然而当\(n\leq 100000\)的时候很明显gg了
发现状态数组的第二维实际上跟这个节点的深度有关,于是考虑用长链剖分优化。(不知道什么是长链剖分的可以看看蒟蒻的笔记)简单来说记每一个节点深度最大的儿子为它的重儿子。因为第一次转移的时候有\(f[u][i]=f[v][i-1],g[u][i]=g[v][i+1]\),于是可以类似于dsu on tree的思想,对于每个重儿子的信息直接继承,轻儿子暴力跑一遍。重儿子的信息可以直接用指针来达到\(O(1)\)的转移
这个时间复杂度大概是\(O(n)\)的,对于每个点转移的复杂度为\(\sum dep[v]-dep[son[u]]=\sum dep[v]-dep[u]+1\),然后所有点的加起来除了叶子结点都互相抵消,于是总的复杂度为\(O(n)\)
空间复杂度也是\(O(n)\),因为非叶节点的空间都是由它所在重链的儿子转移来的,所以对每个叶节点开正比于此重链长度的空间即可
//minamoto
#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
int read(){
int res,f=1;char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=1e5+5,M=1005;
int head[N],Next[N<<1],ver[N<<1],tot;
inline void add(int u,int v){ver[++tot]=v,Next[tot]=head[u],head[u]=tot;}
ll memp[N*5],*f[N],*g[N],*to=memp+5,ans;
int n,dep[N],mx[N];
void dfs(int u,int fa){
mx[u]=u;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa){
dep[v]=dep[u]+1,dfs(v,u);
if(dep[mx[v]]>dep[mx[u]])mx[u]=mx[v];
}
}
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa&&(mx[v]!=mx[u]||u==1)){
v=mx[v],to+=dep[v]-dep[u]+1;
f[v]=to,g[v]=(to+=1),to+=(dep[v]-dep[u])*2+1;
}
}
}
void dp(int u,int fa){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];if(v==fa)continue;dp(v,u);
if(mx[v]==mx[u])f[u]=f[v]-1,g[u]=g[v]+1;
}
ans+=g[u][0],f[u][0]=1;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];if(v==fa||mx[v]==mx[u])continue;
for(int j=0;j<=dep[mx[v]]-dep[u];++j)
ans+=f[u][j-1]*g[v][j]+g[u][j+1]*f[v][j];
for(int j=0;j<=dep[mx[v]]-dep[u];++j){
g[u][j-1]+=g[v][j];
g[u][j+1]+=f[u][j+1]*f[v][j];
f[u][j+1]+=f[v][j];
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);
while(to!=memp)*to=0,--to;*to=0,++to;
dep[1]=1;dfs(1,0),dp(1,0);
printf("%lld\n",ans);return 0;
}
BZOJ4543/BZOJ3522 [POI2014]Hotel加强版(长链剖分)的更多相关文章
- 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP
[BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...
- bzoj4543 [POI2014]Hotel加强版 长链剖分+树形DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4543 题解 这道题的弱化版 bzoj3522 [POI2014]Hotel 的做法有好几种吧. ...
- BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP
题意参见BZOJ3522 n<=100000 数据范围增强了,显然之前的转移方程不行了,那么不妨换一种. 因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方 ...
- BZOJ3522&4543 [POI2014]Hotel加强版 长链剖分
上上周见fc爷用长链剖分秒题 于是偷偷学一学 3522的数据范围很小 可以暴力枚举每个点作为根节点来dp 复杂度$O(n^2)$ 考虑令$f[x][j]$表示以$x$为根的子树内距离$x$为$j$的点 ...
- BZOJ.4543.[POI2014]Hotel加强版(长链剖分 树形DP)
题目链接 弱化版:https://www.cnblogs.com/SovietPower/p/8663817.html. 令\(f[x][i]\)表示\(x\)的子树中深度为\(i\)的点的个数,\( ...
- 【bzoj4543】[POI2014]Hotel加强版
题目 抄题解.jpg 发现原来的\(O(n^2)\)的换根\(dp\)好像行不通了呀 我们考虑非常牛逼的长链剖分 我们设\(f[x][j]\)表示在\(x\)的子树中距离\(x\)为\(j\)的点有多 ...
- bzoj 3522 / 4543 [POI 2014] Hotel - 动态规划 - 长链剖分
题目传送门 bzoj 3522 需要root权限的传送点 bzoj 4543 快速的传送点 慢速的传送点 题目大意 给定一棵树,问有多少个无序三元组$(x, y, z)$使得这三个不同点在树上两两距离 ...
- 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 ...
- 【BZOJ3522】【BZOJ4543】【POI2014】Hotel 树形DP 长链剖分 启发式合并
题目大意 给你一棵树,求有多少个组点满足\(x\neq y,x\neq z,y\neq z,dist_{x,y}=dist_{x,z}=dist_{y,z}\) \(1\leq n\leq 1 ...
随机推荐
- 【Codeforces 1031C】Cram Time
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 如果找到最大的n使得1+2+...+n<=a+b 然后第一天输出1,2.3,4....t1 这里1+2+..+t1<=a 这还远远 ...
- 【转】WEB前端调优
首先从一次完整的的请求说起:(以此为例get,www,baidu.com) 1,webbrower 发出request, 2,然后解析www.baidu.com为ip,找到ip的服务器, 3,服务器处 ...
- mongodb shell 无法删除问题
1.MongoDB Shell中退格键使用的问题. 利用SecureCRT工具访问linux的时候,在使用MongoDB的交互式shell的时候,退格键(Backspace)无法使用,导致无 法修改输 ...
- multi cookie & read bug
js cookie multi cookie & read bug document.cookie; // "access_token_test=eyJhbGciOiJIUzI1Ni ...
- DRF:过滤&搜索&排序功能
过滤功能利用的是第三方包 django_filters,搜索和排序利用的是 Django DRF 提供的 filters 示例代码如下: from rest_framework import filt ...
- 序列终结者(bzoj 1521)
Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...
- 静态区间第k大(归并树)
POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...
- idea中javaweb的mysql8.0.15配置问题
mysql8.0.x以后的版本在连接数据库的时候有些不同. 首先: Class.forName("com.mysql.cj.jdbc.Driver"); 其次: DriverMan ...
- freemarker导出word的一些问题
首先,了解下freemarker导出word的流程: 参考https://www.cnblogs.com/llfy/p/9303208.html 异常一: freemarker.core.ParseE ...
- 洛谷 P1555 尴尬的数字
P1555 尴尬的数字 题目背景 Bessie刚刚学会了不同进制数之间的转换,但是她总是犯错误,因为她的两个前蹄不能轻松的握住钢笔. 题目描述 每当Bessie将一个数转换成新的进制时,她总会写错一位 ...