【学习笔记 边分树】【uoj400】【CTSC2018】暴力写挂
题目
描述
有两棵树\(T\)和\(T'\),节点个数都为\(n\),根节点都为\(1\)号节点;
求两两点之间
\begin{align}
depth(x) + depth(y) - depth(LCA(x,y)) - depth'(LCA'(x,y))
\end{align}
\\
其中depth(x)为x和1号节点的树上距离
\\
\]
的最大值;
范围
$1 \le n \le 366666 $ ;
题解
原式 = \(\frac{(dep(x) + dep(y) + dis(x,y)) }{2} -dep'(x,y)\) ;
枚举第二颗树的节点\(u\),只需要查询\(u\)的各个子树之间的答案;
考虑查询一个对很多点的左边的式子时,可以直接用边分治;
询问两个子树之间的答案也可以用边分治,复杂度是\(O(n^2log \ n)\)的;
注意到边分树是一个二叉树的结构,直接采用线段树和并的写法合并;
学习了一下边分治:
- 每次选择一条边\((u,v)\),使得两边的子树最大\(size\)最小,不断分治;
- 考虑直接分析复杂度:
- 这部分理论是\(cjl\)老师在济南讲课的时候说的,网上说了这个的好少。。。。
- 设整棵树最大的度数为\(D\),\(u\)的子树大小为\(s\),不妨令:\(u \ge n - s\);
- \(u\)的子树大小最大的儿子的子树大小是\(p\);
- 直接有:$p \ge \frac{s-1}{D-1} $ ;
- 同时由于\((u,v)\)是最优的决策,一定有:$n - p \ge s $;
- 解得:$s \le \frac{n(D-1) + 1}{D} $ ;
- 意思是每次的联通块大小是以约\(\frac{D-1}{D}\)的倍数缩小;
- 当\(D\)是个常数时复杂度是\(log\)的,所以直接考虑将图变成一颗二叉树;
黑色的点和边代表原图中的边,绿色的点和边代表虚点和虚边;
-新图的大小为原图的两倍;注意对边权和点权的修改因题而异;
另外意外看到\(dsu \ on \ tree\) ;
- 适用于一些删除比较麻烦的树上数据结构,不支持修改;
- \(dfs\)并树剖,当一个节点做完了存储了子树的信息;
- 假设我们有一个支持插入和完全清零的全局数据结构\(Ds\),一次操作是\(O(Ds)的\);
- 每次先做轻儿子,做完后枚举子树节点暴力清空和轻儿子子树有关的\(Ds\)信息;
- 所以当做完\(u\)的所有儿子回溯到\(u\)时,\(Ds\)中只存在\(u\)的重儿子的子树的影响;
- 再做一遍所有轻儿子的子树,插入到\(Ds\)中去;
- 当一个点被遍历的时候一定是出现了一条轻链;
- 一个点向上的轻链个数为\(O(log \ n)\)的,所以为\(O(n log \ n \ Ds)\);
- 套用到本题得到一个\(O(n log^2 \ n)\)的做法;
//这份代码过不了uoj的extra test ,luogu上会T一个点,暂时还没有修改;
include<bits/stdc++.h>
define mk make_pair
define fi first
define se second
define pb push_back
define inf 1e18
define ll long long
using namespace std;
const int N=366666<<2,M=22;
int n,o,hd[N],cnt,rt,mn,Rt[N],ls[N],rs[N],fa[N];
int vis[N],size,sz[N],d[N],tot,lc[NM],rc[NM];
ll dep[N],dis[M][N],val[N],mxl[NM],mxr[NM],wv[NM],ans=-inf;
struct Edge{int v,nt,w;}E[N];
typedef pair<int,int>pii;
vectorg[N];
char gc(){
static charp1,p2,s[1000000];
if(p1p2)p2=(p1=s)+fread(s,1,1000000,stdin);
return(p1p2)?EOF:p1++;
}
int rd(){
int x=0,f=1;char c=gc();
while(c<'0'||c>'9'){if(c'-')f=-1;c=gc();}
while(c>='0'&&c<='9'){x=x10+c-'0';c=gc();}
return xf;
}
void upd(ll&x,ll y){if(x<y)x=y;}
void adde(int u,int v,int w){
E[o]=(Edge){v,hd[u],w};hd[u]=o++;
E[o]=(Edge){u,hd[v],w};hd[v]=o++;
}
void dfs1(int u,int F){
for(int i=0,lst=0;i<(int)g[u].size();++i){
int v=g[u][i].fi,w=g[u][i].se;
if(vF)continue;
dep[v]=dep[u]+w;dfs1(v,u);
if(!lst){adde(u,v,w);lst=u;continue;}
adde(lst,++cnt,0);adde(cnt,v,w);lst=cnt;
}
}
void get_rt(int u,int F){
sz[u]=1;
for(int i=hd[u];~i;i=E[i].nt){
int v=E[i].v;
if(vis[i]||vF)continue;
get_rt(v,u);sz[u]+=sz[v];
int t=max(size-sz[v],sz[v]);
if(mn>=t)rt=i,mn=t;
}
}
void calc(int d,int u,int F,ll now){
dis[d][u]=now;
for(int i=hd[u];~i;i=E[i].nt){
int v=E[i].v;
if(vis[i]||vF)continue;
calc(d,v,u,now+E[i].w);
}
}
int solve(int u,int F){
if(size1){fa[u]=F;return u;}
int now=++cnt;
rt=-1;mn=size;get_rt(u,0);
val[now]=E[rt].w;
vis[rt]=vis[rt^1]=1;
d[now]=d[fa[now]=F]+1;
int v1=E[rt].v,v2=E[rt^1].v;
calc(d[now],v1,0,0);
calc(d[now],v2,0,0);
size-=sz[v1];rs[now]=solve(v2,now);
size=sz[v1];ls[now]=solve(v1,now);
return now;
}
int ins(int x){
for(int u=fa[x],v=x,lst=0;u;v=u,u=fa[u]){
wv[++tot]=val[u];mxl[tot]=mxr[tot]=-inf;
if(ls[u]v)mxl[tot]=dep[x]+dis[d[u]][x],lc[tot]=lst;
else mxr[tot]=dep[x]+dis[d[u]][x],rc[tot]=lst;
lst=tot;
}
return tot;
}
int merge(int x,int y,ll&tmp){
if(!x||!y)return x+y;
upd(tmp,wv[x]+max(mxl[x]+mxr[y],mxl[y]+mxr[x]));
mxl[x]=max(mxl[x],mxl[y]);
mxr[x]=max(mxr[x],mxr[y]);
lc[x]=merge(lc[x],lc[y],tmp);
rc[x]=merge(rc[x],rc[y],tmp);
return x;
}
void dfs2(int u,int F,ll now){
Rt[u]=ins(u);
upd(ans,dep[u]-now);
ll tmp=-inf;
for(int i=hd[u];~i;i=E[i].nt){
int v=E[i].v;
if(v==F)continue;
dfs2(v,u,now+E[i].w);
Rt[u]=merge(Rt[u],Rt[v],tmp);
}
upd(ans,(tmp>>1)-now);
}
int main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
cnt=n=rd();
memset(hd,-1,sizeof(hd));
for(int i=1,u,v,w;i<n;++i){
u=rd(),v=rd(),w=rd();
g[u].pb(mk(v,w));
g[v].pb(mk(u,w));
}
dfs1(1,0);
mxl[0]=mxr[0]=wv[0]=-inf;
size=cnt;solve(1,0);
o=0;memset(hd,-1,sizeof(hd));
for(int i=1;i<n;++i){
int u=rd(),v=rd(),w=rd();
adde(u,v,w);
}
dfs2(1,0,0);
cout<<ans<<endl;
return 0;
}
【学习笔记 边分树】【uoj400】【CTSC2018】暴力写挂的更多相关文章
- [CTSC2018]暴力写挂——边分树合并
[CTSC2018]暴力写挂 题面不错 给定两棵树,两点“距离”定义为:二者深度相加,减去两棵树上的LCA的深度(深度指到根节点的距离) 求最大的距离. 解决多棵树的问题就是降维了. 经典的做法是边分 ...
- BZOJ5341: [Ctsc2018]暴力写挂
BZOJ5341: [Ctsc2018]暴力写挂 https://lydsy.com/JudgeOnline/problem.php?id=5341 分析: 学习边分治. 感觉边分治在多数情况下都能用 ...
- [LOJ#2553][CTSC2018]暴力写挂
[LOJ#2553][CTSC2018]暴力写挂 试题描述 temporaryDO 是一个很菜的 OIer .在 4 月,他在省队选拔赛的考场上见到了<林克卡特树>一题,其中 \(k = ...
- BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP
题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...
- 并不对劲的bzoj5341:loj2553:uoj400:p4565:[Ctsc2018]暴力写挂
题目大意 有两棵\(n\)(\(n\leq366666\))个节点的树,\(T\)和\(T'\),有边权 \(dep(i)\)表示在\(T\)中\(i\)号点到\(1\)号点的距离,\(dep'(i) ...
- [CTSC2018]暴力写挂
题目描述 www.lydsy.com/JudgeOnline/upload/201805/day1(1).pdf 题解 首先来看这个我们要最大化的东西. deep[u]+deep[v]-deep[lc ...
- bzoj 5341: [Ctsc2018]暴力写挂
Description Solution 边分治+边分树合并 这个题很多做法都是启发式合并的复杂度的,都有点卡 以前有个套路叫做线段树合并优化启发式合并,消掉一个 \(log\) 这个题思路类似,建出 ...
- 题解 「CTSC2018暴力写挂」
题目传送门 题目大意 给出两个大小为 \(n\) 的树,求出: \[\max\{\text{depth}(x)+\text{depth}(y)-\text{depth}(\text{LCA}(x,y) ...
- UOJ400/LOJ2553 CTSC2018 暴力写挂 边分治、虚树
传送门--UOJ 传送门--LOJ 跟隔壁通道是一个类型的 要求的式子中有两个LCA,不是很方便,因为事实上在这种题目中LCA一般都是枚举的对象-- 第二棵树上的LCA显然是动不了的,因为没有其他的量 ...
随机推荐
- .NET持续集成与自动化部署之路第二篇——使用NuGet.Server搭建公司内部的Nuget(包)管理器
使用NuGet.Server搭建公司内部的Nuget(包)管理器 前言 Nuget是一个.NET平台下的开源的项目,它是Visual Studio的扩展.在使用Visual Studio开发基 ...
- ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十四节--后台工作者HangFire与ABP框架Abp.Hangfire及扩展
返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 HangFire与Quartz.NET相比主要是HangFire的内置提供集成化的控制台,方便后台查看及监控,对于 ...
- os模块 与 sys模块
os模块 os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工 ...
- #个人博客作业Week2——关于代码规范的讨论
<1> 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 反驳:官僚制度在一定程度下维持了社会的和谐稳定,一个没有法律.没有拥有完善的管理体制.完全崇尚 ...
- Python学习笔记 --第二章
Python语法基础 "#"号为注释符,建议缩进四个空格,Python大小写敏感. 数据类型 整数 0,2等等,以0x开头的为十六进制数 浮点数 1.58e9 字符串 用'或"括起来的任意文 ...
- Oracle 控制文件管理
控制文件是一个很小的二进制文件(10MB左右),含有数据库结构信息,包括数据文件和日志文件信息.控制文件在数据库创建时被自动创建,并在数据库发生物理变数时更新.控制文件被不断更新,在任何时候都要保证控 ...
- mysql的主主复制详解
Mysql双主部署 解释: 所谓双主备份,其实也就是互做主从复制,每台master既是master,又是另一台服务器的slave.这样,任何一方所做的变更,都会通过复制应用到另外一方的数据库中. 要求 ...
- Java微信二次开发(十)
生成带参数的二维码以及长链接转短链接 第一步:找到包com.wtz.vo,新建类WeixinQRCode.java package com.wtz.vo; /** * @author wangtian ...
- c#异步编程(三)—ASP.NET MVC 异步控制器及EF异步操作
ASP.NET MVC 异步控制器及EF异步操作 异步控制器 ASP.NET MVC2后开始了对异步请求管道的支持,异步请求管道的作用是允许web服务器处理长时间运行的请求,比如 那些花费大量时间等待 ...
- 配置dataimport时候 如果css样式有问题 要修改index和admin的版本号