题目:https://www.luogu.org/problemnew/show/P4115

论文:https://wenku.baidu.com/view/1bc2e4ea172ded630b1cb602.html

重链剖分,分别用线段树维护每条重链。线段树叶子的信息是该点轻孩子的信息;线段树区间的信息是考虑重链的一个区间以及附带的轻孩子们的信息。

修改一个点,改它所在的重链的信息。祖先的每条重链都有一个点的 “轻孩子信息” 改变了,改一下那个位置的值,更新它的线段树,再用该重链的信息作为轻孩子更新更上面的重链。

本题每个点要维护的是 “向下以白点为端点的最长链” 和 “向下以白点为端点的次长链” 。用可删堆维护。

线段树区间维护 “从左边开始、以白点结束的最长链” 、 “从右边开始、以白点结束的最长链” 、 “中间一条两端点都是白点的最长链” 。前两个信息是为了更新第三个信息。

每条重链的答案放进全局可删堆中。

注意求 “次长链” 的时候,自己是先把堆顶拿出来,再看剩下的堆的堆顶。要注意再看之前先用删除堆更新一下!

预处理的时候,自己想一个一个插入。在 pshp 的时候要用到兄弟的 fl , fr , pr , sc 等信息。所以得先把线段树整个建出来,不能有些孩子是空的就开始 pshp 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=1e5+,M=2e5+,INF=1e9,Lm=-1e8;
int n,hd[N],xnt,to[M],nxt[M],w[M]; bool col[N];
int siz[N],son[M],dep[N],fa[N],fw[N],top[N];
int dis[N],dp2[N],lm[N],tot,rt[N],Ls[M],Rs[M];
int dy[N],fl[M],fr[M],mx[M],pr[M],sc[M];
priority_queue<int> q[N],dq[N],ans,dans;
int Dis(int x,int y){return dp2[y]-dp2[x];}
void frs(int x)
{
while(dq[x].size()&&q[x].top()==dq[x].top())
q[x].pop(), dq[x].pop();
}
void pshp(int cr)
{
pr[cr]=pr[ls]; sc[cr]=sc[rs];
fl[cr]=Mx(fl[ls],Dis(pr[cr],pr[rs])+fl[rs]);
fr[cr]=Mx(fr[rs],Dis(sc[ls],sc[cr])+fr[ls]);
mx[cr]=Mx(Dis(sc[ls],pr[rs])+fr[ls]+fl[rs],Mx(mx[ls],mx[rs]));
}
void build(int l,int r,int &cr)
{
cr=++tot;fl[cr]=fr[cr]=mx[cr]=-INF;
pr[cr]=dy[l]; sc[cr]=dy[r];
if(l==r)return; int mid=l+r>>;
build(l,mid,ls); build(mid+,r,rs);
}
void updt(int l,int r,int cr,int p,int k)
{
if(l==r)
{
fl[cr]=fr[cr]=dis[k]; pr[cr]=sc[cr]=k;
if(!q[k].size()){ mx[cr]=-INF; return;}
q[k].pop(); frs(k);//////
int d2=-INF;
if(q[k].size())d2=q[k].top();
if(!col[k])mx[cr]=Mx(dis[k]+d2,Mx(dis[k],d2));
//col[k] not col[cr]!!
else mx[cr]=dis[k]+d2;
q[k].push(dis[k]);
return;
}
int mid=l+r>>;
if(p<=mid)updt(l,mid,ls,p,k); else updt(mid+,r,rs,p,k);
pshp(cr);
}
void add(int x,int y,int z)
{to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;}
void dfs(int cr,int f)
{
dep[cr]=dep[f]+; dp2[cr]=dp2[f]+fw[cr];
fa[cr]=f; siz[cr]=;
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=f)
{
fw[v]=w[i]; dfs(v,cr); siz[cr]+=siz[v];
if(siz[v]>siz[son[cr]])son[cr]=v;
}
}
int Ps(int cr){return dep[cr]-dep[top[cr]]+;}
void dfsx(int cr,int f)
{
if(son[cr])top[son[cr]]=top[cr],dfsx(son[cr],cr);
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=f&&v!=son[cr])
{
top[v]=v;dfsx(v,cr);
if(fl[rt[v]]>Lm)q[cr].push(fl[rt[v]]+w[i]);
}
if(!col[cr])q[cr].push();
if(q[cr].size())dis[cr]=q[cr].top(); else dis[cr]=-INF;
int p=Ps(cr),tp=top[cr];
if(p>lm[tp])
{
lm[tp]=p;
for(int i=p,k=cr;i;i--,k=fa[k])dy[i]=k;
build(,p,rt[tp]);
}
updt(,lm[tp],rt[tp],p,cr);
if(tp==cr)ans.push(mx[rt[cr]]);
}
void chg(int cr)
{
col[cr]=!col[cr];
if(!col[cr])q[cr].push(); else dq[cr].push();
int x=top[cr]; frs(cr);
if(q[cr].size())dis[cr]=q[cr].top(); else dis[cr]=-INF;
dans.push(mx[rt[x]]);
if(fa[x])dq[fa[x]].push(fl[rt[x]]+fw[x]);
updt(,lm[x],rt[x],Ps(cr),cr);
ans.push(mx[rt[x]]);
if(fa[x])q[fa[x]].push(fl[rt[x]]+fw[x]);
while(fa[x])
{
cr=fa[x]; x=top[cr]; frs(cr);
if(q[cr].size())dis[cr]=q[cr].top(); else dis[cr]=-INF;
dans.push(mx[rt[x]]);
if(fa[x])dq[fa[x]].push(fl[rt[x]]+fw[x]);
updt(,lm[x],rt[x],Ps(cr),cr);
ans.push(mx[rt[x]]);
if(fa[x])q[fa[x]].push(fl[rt[x]]+fw[x]);
}
}
int main()
{
n=rdn();
for(int i=,u,v,z;i<n;i++)
{
u=rdn();v=rdn();z=rdn();
add(u,v,z);add(v,u,z);
}
dfs(,); top[]=; dfsx(,);
int Q=rdn(); char ch;int x;
while(Q--)
{
cin>>ch;
if(ch=='A')
{
while(dans.size()&&ans.top()==dans.top())
ans.pop(),dans.pop();
if(ans.top()<Lm)puts("They have disappeared.");
else printf("%d\n",ans.top());
}
else
{ x=rdn(); chg(x);}
}
return ;
}

洛谷 4115 Qtree4——链分治的更多相关文章

  1. 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)

    题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...

  2. 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV

    意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...

  3. 洛谷P3810 陌上花开 CDQ分治(三维偏序)

    好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...

  4. 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器

    刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...

  5. 洛谷P3384 树链剖分

    如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x ...

  6. [洛谷P3806] [模板] 点分治1

    洛谷 P3806 传送门 这个点分治都不用减掉子树里的了,直接搞就行了. 注意第63行 if(qu[k]>=buf[j]) 不能不写,也不能写成>. 因为这个WA了半天...... 如果m ...

  7. 洛谷 P3384 树链剖分(模板题)

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  8. 【树链剖分】洛谷P3379 树链剖分求LCA

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  9. 洛谷P4390 Mokia CDQ分治

    喜闻乐见的CDQ分治被我搞的又WA又T..... 大致思路是这样的:把询问用二维前缀和的思想拆成4个子询问.然后施CDQ大法即可. 我却灵光一闪:树状数组是可以求区间和的,那么我们只拆成两个子询问不就 ...

随机推荐

  1. Jsの练习-数组其他常用方法 -map() ,filter() ,every() ,some()

    map() :映射,对数组中的每一项运行给定函数,返回每次函数调用结果组成的函数. <!DOCTYPE html> <html lang="en"> < ...

  2. Hyperledger Fabric-CA学习

    Hyperleder Fabric系统架构核心逻辑包括MemberShip.Blockchain和Chaincode 其中上述3个核心逻辑中,Membership服务用来管理节点身份.隐私.confi ...

  3. vue 中生成二维码之爬坑之路

    最近在做vue中项目,有个需求是在你提交信息后把后台返给你的链接生成二维码. 一共使用了两种生成二维码的方法 1.vue-qr 这个是在一进入页面直接生成二维码,具体介绍见文档:https://www ...

  4. 20175223 姚明宇 MyCP

    目录 MyCP 要求 代码运行编译及文本输出输入结果 目录树 代码运行编译: 文本输出输入结果: 源代码 码云链接 目录 MyCP 要求 编写MyCP.java 实现类似Linux下cp XXX1 X ...

  5. python网络编程(UDP+广播)

    UDP广播案例,一端发送,多端接受: 发送端: # UDP广播案例 from socket import * from time import sleep # 设定目标地址 dest=('176.21 ...

  6. 汉诺塔III

    题目描述: 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动 ...

  7. Java ASM 技术简介

    什么是ASM ASM 是一个 Java 字节码操控框架.它能被用来动态生成类或者增强既有类的功能.ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为. ...

  8. 在过去五分钟内,TypeScript语言服务以外终止了5次

    这个问题困扰了我两次...第一次重装了VS CODE 具体的原意找到之后我直接想骂娘....... 各位如果碰到这个问题....请打开你的360安全卫士!!! 注意看看您家360的防护日志有木有贴心帮 ...

  9. go语言关于线程与通道channal

    在go语言中,封装了多线程的使用方法,使其变得简单易用. 在这里说说自己一点体会,不正确的地方还是请各位大牛指正. 关于go语言的并发机制,这很简单,在你要执行的函数前面加上go即可 比如: pack ...

  10. java第六周作业

    1  JSF请求处理生命周期的高度概述 从历史上看,Web应用程序必需的大部分开发,主要是处理Web客户端的HTTP请求.随着Web从传统的静态文档传送模型(在这种模型中,只请求静态Web页面,没有参 ...