题目: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. Linux监控

    第三十次课 Linux监控 目录 一. Linux监控平台介绍 二. zabbix监控介绍 三. 安装zabbix 四. 忘记Admin密码如何做 五. 主动模式和被动模式 六. 添加监控主机 七. ...

  2. nginx 多域名指向多个根目录配置,设置自定义请求头 proxy_set_header,ssl 证书安装配置

    1.nginx.conf 配置文件引入子配置文件 include vhost-server/*.conf;  关键在 server_name  不同域名执行不同的根 user root; #user ...

  3. WEB 设计规范

    WEB端设计规范 一.网页尺寸       一般网站宽为996px:国内网站大部分还是以1000个像素为界限,因超过1000像素适合在大屏幕上浏览,小屏幕会显得拥挤.国内尺寸设置比较保守,这样可以保证 ...

  4. Mac OSX 编译 LeanSDR

    LeanSDR:Lightweight, portable software-defined radio git clone http://github.com/pabr/leansdr.git cd ...

  5. Laravel Scout 开启队列, 自定义queue name和queue connection

    scout.php的默认配置: 'queue' => env('SCOUT_QUEUE', false), 修改为: 'queue' => [ 'queue' => env('SCO ...

  6. PaperBye-一个可以自动改重的免费论文查重网站

    推荐一个自动降重的免费论文查重软件,可自动降低论文重复率,一边修改,一边查重,免费查重网址:https://www.paperbye.com

  7. 看到Console.WriteLine($"string")写法,一时间不理解$的用途

    参了网上资料,原来它是C# 6.0的语法糖. C# 6.0 新加上的功能:   Null-Conditional Operator 大概就是,简洁代码量,缩短一些关于为null的判断~ 旧写法: pu ...

  8. you-get 下载视频

    亲测有效,没在别的平台试,道理是相通的 平台:Windows 10 所需工具: python3,pip3,you-get 步骤流程: 正确安装python3,配置环境变量 (目前使用的是3.6+) 打 ...

  9. 微信小程序上传文件遇到的坑

    在开发小程序时,使用的花生壳做的内网映射,域名使用花生壳卖的https域名 在做小程序文件上传时,调用接口,老是报错. Caused by: org.apache.commons.fileupload ...

  10. Android Studio 入口程序的设置方法

    在src -> main中 ,打开 AndroidManifest.xml 这个文件 下面这里有两个窗口,如果要想把哪个窗口设置成入口窗体,只要把下面红色的放在这个节点中就可以了 <act ...