传送门

做一道题学一堆东西.jpg

猫老师的题……暴力拿的分好像比打挂的正解多很多啊……我纯暴力+部分分已经能有80了……正解没调对之前一直只有10分→_→

先说一下什么是边分治。这个其实类似于点分治,不过分治对象从点换成边了,就是每次找到一条边,使其断开之后的两个连通块中最大的最小

于是我们就可以……等会儿如果在菊花图上怎么办?不是得卡到\(O(n^2)\)了?

不难发现这个东西的复杂度和节点的度数有关,于是为了假装这个东西能用避免这些情况,我们要把图给重构喽

简单来说就是通过加入虚点,把图给搞成一棵二叉树,这样的话节点度数就小了,复杂度也没问题了

原理大概就这样,具体实现还是看代码比较好

然后回到本题

首先在第二棵树上的\(LCA\)的深度它就不是个东西,我们只能去枚举它,那么能选的点就是它的不同子树中的点了

然后考虑转化一下,$$dep(x) + dep(y) - dep(LCA(x,y))=\frac{1}{2}(dep(x) + dep(y) + dis(x,y))$$

然后我们就可以把它给转化成一棵无根树了

在分治过程中,对于每条边\((i,j)\),要维护两边子树中中最大的\(dep_u+dis_{i,u}\)和\(dep_v+dis_{j,v}\),然后用自己这条边更新答案

然后因为边分树是一棵二叉树,我们可以用线段树来维护上面的信息

然后就没有然后了(就算有然后我也布吉岛是怎么回事)

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define inf 1e18
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(T,u) for(int i=T.head[u],v=T.e[i].v;i;i=T.e[i].nx,v=T.e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R 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=7.5e5+5;
struct eg{int v,nx,w;}st[N];
struct Gr{
eg e[N<<1];int head[N],tot;
inline void add(R int u,R int v,R int w){e[++tot]={v,head[u],w},head[u]=tot;}
}T,G,H;
ll toroot[N];
int n,cnt;
void rebuild(int u,int fa){
int h=1,t=0;
go(T,u)if(v!=fa)toroot[v]=toroot[u]+T.e[i].w,rebuild(v,u);
go(T,u)if(v!=fa)st[++t]=T.e[i];
while(t-h>=2){
eg s1=st[h++],s2=st[h++];
int w=++cnt;st[++t]={w,0,0};
H.add(w,s1.v,s1.w),H.add(s1.v,w,s1.w);
H.add(w,s2.v,s2.w),H.add(s2.v,w,s2.w);
}
while(h<=t)H.add(u,st[h].v,st[h].w),H.add(st[h].v,u,st[h].w),++h;
}
int ls[N<<1],rs[N<<1],fa[N<<1],dif[N],sz[N],dep[N],val[N<<1];ll dis[25][N];
int size;
void getdis(int u,int fat,int dep){
go(H,u)if(v!=fat&&v!=-1){
dis[dep][v]=dis[dep][u]+H.e[i].w;
getdis(v,u,dep);
}
}
void getgr(int u,int fat,int &g1,int &g2){
sz[u]=1;
go(H,u)if(v!=fat&&v!=-1){
getgr(v,u,g1,g2),sz[u]+=sz[v];
if(dif[g2]>dif[v])g1=u,g2=v;
}dif[u]=abs(size-(sz[u]<<1));
}
int gettr(int u,int dep,int s){
if(s==1)return ::dep[u]=dep,u;
getdis(u,0,dep);
int now=++cnt,g1=0,g2=0;
size=s,getgr(u,0,g1,g2);
go(H,g1)if(v==g2){val[now]=H.e[i].w,H.e[i].v=-1;break;}
go(H,g2)if(v==g1){H.e[i].v=-1;break;}
rs[now]=gettr(g1,dep+1,size-sz[g2]);
ls[now]=gettr(g2,dep+1,sz[g2]);
fa[ls[now]]=fa[rs[now]]=now;
return now;
}
void init(){
cnt=n,rebuild(1,0);
dif[0]=0x3f3f3f3f,gettr(1,0,cnt);
}
ll lv[N<<4],rv[N<<4],res;
int id,mp[N<<4],rt[N],lp[N<<4],rp[N<<4];
int merge(int x,int y,ll d){
if(!x||!y)return x|y;
cmax(res,((lv[x]+rv[y]+val[mp[x]])>>1)-d);
cmax(res,((rv[x]+lv[y]+val[mp[x]])>>1)-d);
cmax(lv[x],lv[y]),lp[x]=merge(lp[x],lp[y],d);
cmax(rv[x],rv[y]),rp[x]=merge(rp[x],rp[y],d);
return x;
}
int ins(int u){
for(int i=dep[u],x=u,las=0;i;--i,las=cnt,u=fa[u]){
mp[++cnt]=fa[u];
lv[cnt]=rv[cnt]=-inf;
if(u==ls[fa[u]])cmax(lv[cnt],dis[i][x]+toroot[x]),lp[cnt]=las;
else cmax(rv[cnt],dis[i][x]+toroot[x]),rp[cnt]=las;
}return cnt;
}
void solve(int u,int fat,ll d){
rt[u]=ins(u),cmax(res,toroot[u]-d);
go(G,u)if(v!=fat){
solve(v,u,d+G.e[i].w);
rt[u]=merge(rt[u],rt[v],d);
}
}
int u,v,w;
int main(){
// freopen("testdata.in","r",stdin);
n=read();
fp(i,1,n-1)u=read(),v=read(),w=read(),T.add(u,v,w),T.add(v,u,w);
fp(i,1,n-1)u=read(),v=read(),w=read(),G.add(u,v,w),G.add(v,u,w);
init(),solve(1,0,0);
printf("%lld\n",res);
return 0;
}

uoj#400. 【CTSC2018】暴力写挂(边分治)的更多相关文章

  1. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  2. UOJ400/LOJ2553 CTSC2018 暴力写挂 边分治、虚树

    传送门--UOJ 传送门--LOJ 跟隔壁通道是一个类型的 要求的式子中有两个LCA,不是很方便,因为事实上在这种题目中LCA一般都是枚举的对象-- 第二棵树上的LCA显然是动不了的,因为没有其他的量 ...

  3. 【UOJ#400】暴力写挂

    题目链接 题意 两棵树 , 求出下面式子的最大值. \[dep[u]+dep[v]-dep[LCA(u,v)]-dep'[LCA'(u,v)]\] Sol 边分治. 与第一棵树有关的信息比较多,所以对 ...

  4. [CTSC2018]暴力写挂——边分树合并

    [CTSC2018]暴力写挂 题面不错 给定两棵树,两点“距离”定义为:二者深度相加,减去两棵树上的LCA的深度(深度指到根节点的距离) 求最大的距离. 解决多棵树的问题就是降维了. 经典的做法是边分 ...

  5. [LOJ#2553][CTSC2018]暴力写挂

    [LOJ#2553][CTSC2018]暴力写挂 试题描述 temporaryDO 是一个很菜的 OIer .在 4 月,他在省队选拔赛的考场上见到了<林克卡特树>一题,其中 \(k = ...

  6. BZOJ5341: [Ctsc2018]暴力写挂

    BZOJ5341: [Ctsc2018]暴力写挂 https://lydsy.com/JudgeOnline/problem.php?id=5341 分析: 学习边分治. 感觉边分治在多数情况下都能用 ...

  7. UOJ#400. 【CTSC2018】暴力写挂 边分治 线段树合并

    原文链接 www.cnblogs.com/zhouzhendong/p/UOJ400.html 前言 老年选手没有码力. 题解 先对第一棵树进行边分治,然后,设点 x 到分治中心的距离为 $D[x]$ ...

  8. LOJ 2553 「CTSC2018」暴力写挂——边分治+虚树

    题目:https://loj.ac/problem/2553 第一棵树上的贡献就是链并,转化成 ( dep[ x ] + dep[ y ] + dis( x, y ) ) / 2 ,就可以在第一棵树上 ...

  9. bzoj 5341: [Ctsc2018]暴力写挂

    Description Solution 边分治+边分树合并 这个题很多做法都是启发式合并的复杂度的,都有点卡 以前有个套路叫做线段树合并优化启发式合并,消掉一个 \(log\) 这个题思路类似,建出 ...

  10. 并不对劲的bzoj5341:loj2553:uoj400:p4565:[Ctsc2018]暴力写挂

    题目大意 有两棵\(n\)(\(n\leq366666\))个节点的树,\(T\)和\(T'\),有边权 \(dep(i)\)表示在\(T\)中\(i\)号点到\(1\)号点的距离,\(dep'(i) ...

随机推荐

  1. 有关svg的一些理解

    SVG 是使用XML来描述二维图形和绘图程序的语言. SVG指可伸缩的矢量图形(Scalable Vector Graphics) SVG使用XML格式定义图形 SVG图形在放大或改变尺寸的情况下,图 ...

  2. MVC+Ext.net零基础学习记录(四)

    在上一篇文章[MVC+Ext.net零基础学习记录(三)]中提到了利用MVC的Area可以做到项目分离,但是实际操作起来还是有很多问题的.比如,对于物理资源的访问,会报:没有相关资源 开始的时候,我在 ...

  3. BZOJ 1724 [Usaco2006 Nov]Fence Repair 切割木板:贪心 优先队列【合并果子】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1724 题意: 你要将一块长木板切成n段,长度分别为a[i](长木板的长度 = ∑ a[i] ...

  4. python-常用内置函数与装饰器

    1.常用的python函数 abs             求绝对值 all               判断迭代器中所有的数据是否为真或者可迭代数据为空,返回真,否则返回假 any          ...

  5. Java企业微信开发_10_未验证域名归属,JS-SDK功能受限

    1.现象: 在企业微信后台填写可信域名后,提示:未验证域名归属,JS-SDK功能受限,如下图: 点击“申请域名校验”后, 注意:域名根目录 当时一直不清楚这个域名根目录在哪里,最后让我给试出来了 2. ...

  6. spring2.5整合struts2

    首先第一步: 导入jar包: 我的做法: 导入你的基本使用的spring的jar包 和基本使用的struts2的jar包 然后struts2中有一个和spring整合的jar包一定要导入,不然会抛异常 ...

  7. listen 73

    Give Time to Feel Less Time-Squeeze Meetings, calls, kids, dogs, errands, exercise—and all those ema ...

  8. codeforces 705B B. Spider Man(组合游戏)

    题目链接: B. Spider Man time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. MySQL活动期间制定月份注册用户下单情况_20161029

    在10.29到10.31号期间 10月新注册的用户订单金额满600元赠与优惠券 #3天内订单满600元且10月注册的用户订单明细 SELECT a.城市,a.用户ID,b.用户名称,DATE(b.注册 ...

  10. BZOJ_2259_ [Oibh]新型计算机 _最短路

    Description Tim正在摆弄着他设计的“计算机”,他认为这台计算机原理很独特,因此利用它可以解决许多难题. 但是,有一个难题他却解决不了,是这台计算机的输入问题.新型计算机的输入也很独特,假 ...