洛谷 4115 Qtree4——链分治
题目: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——链分治的更多相关文章
- 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)
题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV
意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...
- 洛谷P3810 陌上花开 CDQ分治(三维偏序)
好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...
- 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器
刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...
- 洛谷P3384 树链剖分
如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x ...
- [洛谷P3806] [模板] 点分治1
洛谷 P3806 传送门 这个点分治都不用减掉子树里的了,直接搞就行了. 注意第63行 if(qu[k]>=buf[j]) 不能不写,也不能写成>. 因为这个WA了半天...... 如果m ...
- 洛谷 P3384 树链剖分(模板题)
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
- 【树链剖分】洛谷P3379 树链剖分求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 洛谷P4390 Mokia CDQ分治
喜闻乐见的CDQ分治被我搞的又WA又T..... 大致思路是这样的:把询问用二维前缀和的思想拆成4个子询问.然后施CDQ大法即可. 我却灵光一闪:树状数组是可以求区间和的,那么我们只拆成两个子询问不就 ...
随机推荐
- readme 语法
README =========================== 该文件用来测试和展示书写README的各种markdown语法.GitHub的markdown语法在标准的markdown语法基础 ...
- 极速在mac中安装python开发环境
mac开发环境的安装: brew: 包管理工具{ 安装:ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/in ...
- windows 下安装MySQL 服务无法启动类问题
解决方案: 1 执行 mysqld.exe -nt remove 2 执行 mysqld --initialize(中间是两个中划线) 3 执行 mysqld.exe -nt install 4 执行 ...
- 微信小程序实际开发中学习
三个概念 微信:就是一个聊天工具 微信公众号:企业或个人用于管理其粉丝/用户的应用(类似于APP) 微信小程序:不需要下载安装直接可以使用的软件/应用/APP 小程序与公众号的区别: 定位不同(小程序 ...
- Element-ui 更新tableData 中 row的某一个属性时,没有更新视图的问题
在一个报警音管理的页面中,每次点击试听的时候,需要把‘试听’ 更新为 ‘停止’, 起初我们给row.play=0时,显示为 试听,row.play=1时显示为停止, 但是在代码中每次为row.play ...
- Linux 驱动——Button驱动4(fasync)异步通知
button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...
- Prime31
https://prime31.com/plugins
- 面向对象的JavaScript-小结
Javascript中的类 类是对象的模板,用于创建共享一系列属性和方法的类似对象. 使用new关键字调用函数,可以创建对象实例. function Accommodation(){}; var ho ...
- 三维机翼某一断面的压力系数X-Y曲线绘制——使用tecplot的extract功能
目标:绘制三维物体表面或者某等值面上某一截断线上的压力系数X-Y曲线 Slices不光可以在一个体上切出来一个平面,还可以和一个面相交切出一条曲线,命令是在Slice Details里面的Slice ...
- 如何在Linux上设置SSH密码以进行无密码登录(转)
ssh(secure shell)广泛用于远程登录Linux服务器.当我们使用ssh登录到远程系统时,它会提示输入密码,然后只允许我们登录到服务器.有时我们需要配置应用程序或脚本(主要是shell脚本 ...