我们考虑树剖,线段树上维护一个堆,保存不经过该段区间的路径的权值。 
对于一条路径我们将对于线段树中的区间提取出来,在对于线段树中进行修改。也就是在堆中插入或删除。 
对于一次询问,只要找到包含该点的线段中堆顶权值最大的就行了。

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std; typedef long long LL; #define N 200010 struct data
{
int l,r;
}q[N]; struct edge
{
int s,to,next;
}e[N<<];
int head[N<<];
int cnt; int dep[N],siz[N],son[N],top[N],pos[N];
int fa[N][],val[N<<]; bool vis[N]; int n,m;
int ans,res,num; int askd; struct cmp
{
bool operator() (int a,int b)
{
return val[a]<val[b];
}
}; priority_queue<int,vector<int>,cmp> Q[N<<]; bool cmp(data a,data b)
{
return a.l<b.l;
} void link(int x,int y)
{
e[++cnt]=(edge){x,y,head[x]};
head[x]=cnt;
} void dfs(int x)
{
siz[x]=;
son[x]=;
for (int i=head[x];i;i=e[i].next)
{
int t=e[i].to;
if (t!=fa[x][])
{
dep[t]=dep[x]+;
fa[t][]=x;
dfs(t);
siz[x]+=siz[t];
if (siz[t]>siz[son[x]])
son[x]=t;
}
}
} void dfs2(int x,int cha)
{
pos[x]=++res;
top[x]=cha;
if (son[x])
dfs2(son[x],cha);
for (int i=head[x];i;i=e[i].next)
{
int t=e[i].to;
if (t!=fa[x][] && t!=son[x])
dfs2(t,t);
}
} void build_lca()
{
for (int j=;j<=;j++)
for (int i=;i<=n;i++)
if (fa[i][j-])
fa[i][j]=fa[fa[i][j-]][j-];
} int lca(int x,int y)
{
if (dep[x]<dep[y])
swap(x,y);
int t=dep[x]-dep[y];
for (int i=;i>=;i--)
if (t & (<<i))
x=fa[x][i];
if (x==y)
return x;
for (int i=;i>=;i--)
if (fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
} void add(int nowl,int nowr,int now,int l,int r,int d)
{
if (l<=nowl && nowr<=r)
{
Q[now].push(d);
return ;
}
int mid=(nowl+nowr)>>;
if (l<=mid)
add(nowl,mid,now<<,l,r,d);
if (r>=mid+)
add(mid+,nowr,now<<|,l,r,d);
} void query(int nowl,int nowr,int now,int d)
{
while (!Q[now].empty())
{
int k=Q[now].top();
if (vis[k])
Q[now].pop();
else
{
num=max(num,val[k]);
break;
}
}
if (nowl==nowr)
return ;
int mid=(nowl+nowr)>>;
if (d<=mid)
query(nowl,mid,now<<,d);
else
query(mid+,nowr,now<<|,d);
}
int main()
{
scanf("%d%d",&n,&m);
int x,y;
for (int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
link(x,y);
link(y,x);
}
dep[]=;
dfs();
dfs2(,);
build_lca();
for (int i=;i<=m;i++)
{
scanf("%d",&askd);
if (askd==)
{
scanf("%d%d%d",&x,&y,&val[i]);
int w=,z=lca(x,y);
while (dep[top[x]]>dep[z])
{
q[++w]=(data){pos[top[x]],pos[x]};
x=fa[top[x]][];
}
while (dep[top[y]]>dep[z])
{
q[++w]=(data){pos[top[y]],pos[y]};
y=fa[top[y]][];
}
if (x!=z)
q[++w]=(data){pos[z],pos[x]};
else if (y!=z)
q[++w]=(data){pos[z],pos[y]};
else
q[++w]=(data){pos[z],pos[z]};
q[++w]=(data){n+,n+};
sort(q+,q+w+,cmp);
for (int j=;j<=w;j++)
if (q[j-].r<q[j].l-)
add(,n,,q[j-].r+,q[j].l-,i);
}
else if (askd==)
{
scanf("%d",&x);
vis[x]=;
}
else
{
scanf("%d",&x);
num=-;
query(,n,,pos[x]);
printf("%d\n",num);
}
}
return ;
}

【bzoj4538】[Hnoi2016]网络的更多相关文章

  1. BZOJ4538 HNOI2016网络(树链剖分+线段树+堆/整体二分+树上差分)

    某两个点间的请求只对不在这条路径上的询问有影响.那么容易想到每次修改除该路径上的所有点的答案.对每个点建个两个堆,其中一个用来删除,线段树维护即可.由于一条路径在树剖后的dfs序中是log个区间,所以 ...

  2. BZOJ4538 : [Hnoi2016]网络

    求出这棵树的dfs序,对于一条链$u-v$,假设$st[u]\leq st[v]$,那么一条链不经过点$x$当且仅当它满足下面任意一个条件: 1.$st[v]<st[x]$ 2.$st[u]&g ...

  3. 2019.01.13 bzoj4538: [Hnoi2016]网络(树链剖分)

    传送门 树链剖分一眼题. 题意简述: 给定一棵树,有三种操作: 加入一条路径 删除一条已加入的路径 询问不过一个点x的路径的最大值. 思路: 直接树链剖分维护答案. 因为询问的事不过点xxx的最大值, ...

  4. BZOJ4538:[HNOI2016]网络(树链剖分,堆)

    Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...

  5. 【BZOJ4538】[Hnoi2016]网络 整体二分+树状数组

    [BZOJ4538][Hnoi2016]网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互 ...

  6. BZOJ 4538: [Hnoi2016]网络 [整体二分]

    4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...

  7. 【LG3250】[HNOI2016]网络

    [LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...

  8. 4538: [Hnoi2016]网络

    4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...

  9. [HNOI2016]网络 树链剖分,堆

    [HNOI2016]网络 LG传送门 表示乱搞比正解难想. 整体二分很好想吧. 但是为了好写快乐,我们选择三个\(\log\)的乱搞. 先树剖,线段树套堆维护区间最大值.对于一次修改,如果是插入,就把 ...

  10. Luogu-3250 [HNOI2016]网络

    Luogu-3250 [HNOI2016]网络 题面 Luogu-3250 题解 CDQ分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...

随机推荐

  1. jQuery动态移除和绑定事件

    function bindEvent() { //移除绑定事件 $('.btnsp').unbind('click'); //绑定事件 $('.btnsp').bind('click', functi ...

  2. jQuery-鼠标经过显示大图并跟随鼠标效果方法封装

    //copyright c by zhangxinxu 2019-1-15 /*由于大图绑定在href属性中,故一般而言,需使用a标签的href指向大图.仅支持png,gif,jpg,bmp四种格式的 ...

  3. JavaScript异步编程解决方案探究

    javascript的天生单线程特性,使得异步编程对它异常重要,早期的通常做法是用回调函数来解决.但是随着逻辑的复杂,和javascript在服务端的大显神通,使得我们很容易就陷入“回调陷井”的万丈深 ...

  4. node 转二进制 图片

    'use strict';const Service = require('egg').Service;const fs = require('fs');const path = require('p ...

  5. [LUOGU] P3354 [IOI2005]Riv 河流

    题目描述 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海.这条大河的入海口处有一个村庄--名叫 ...

  6. UVA 1596 Bug Hunt (大模拟 栈)

    题意: 输入并模拟执行一段程序,输出第一个bug所在的行. 每行程序有两种可能: 数组定义: 格式为arr[size]. 例如a[10]或者b[5],可用下标分别是0-9和0-4.定义之后所有元素均为 ...

  7. IE & table & border & border-collapse & bug

    shit IE table border bug & border-collapse bug > `border-collapse: collapse;` table { width: ...

  8. linux 常见名词及命令(三)

    tar 用于对文件打包压缩或解压. 示例: 打包并压缩文件:tar -czvf 压缩包名.tar.gz 文件名 解压并展开压缩包:tar -zxvf 压缩包名.tar.gz -c 创建压缩文件 -x ...

  9. 交互设计:隐藏或显示大段文本的UI组件有哪些?

    应用场景: 在手机上要给列表中的每一项添加一个大段的介绍,应该用什么UI组件 A: 这里可以用,模态对话框,弹出提示,工具提示这类组件.模态对话框的好处,就是用关闭的按钮,用户操作方便:而弹出提示和工 ...

  10. Delphi:Indy9的IdFTP完全使用

    Delphi 7自带的INDY控件,其中包含了IdFTP,可以方便的实现FTP客户端程序,参考自带的例子,其中有上传.下载.删除文件,但是不包含对文件夹的操作,得自己实现上传.下载.删除整个文件夹(带 ...