【bzoj4538】[Hnoi2016]网络
我们考虑树剖,线段树上维护一个堆,保存不经过该段区间的路径的权值。
对于一条路径我们将对于线段树中的区间提取出来,在对于线段树中进行修改。也就是在堆中插入或删除。
对于一次询问,只要找到包含该点的线段中堆顶权值最大的就行了。
#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]网络的更多相关文章
- BZOJ4538 HNOI2016网络(树链剖分+线段树+堆/整体二分+树上差分)
某两个点间的请求只对不在这条路径上的询问有影响.那么容易想到每次修改除该路径上的所有点的答案.对每个点建个两个堆,其中一个用来删除,线段树维护即可.由于一条路径在树剖后的dfs序中是log个区间,所以 ...
- BZOJ4538 : [Hnoi2016]网络
求出这棵树的dfs序,对于一条链$u-v$,假设$st[u]\leq st[v]$,那么一条链不经过点$x$当且仅当它满足下面任意一个条件: 1.$st[v]<st[x]$ 2.$st[u]&g ...
- 2019.01.13 bzoj4538: [Hnoi2016]网络(树链剖分)
传送门 树链剖分一眼题. 题意简述: 给定一棵树,有三种操作: 加入一条路径 删除一条已加入的路径 询问不过一个点x的路径的最大值. 思路: 直接树链剖分维护答案. 因为询问的事不过点xxx的最大值, ...
- BZOJ4538:[HNOI2016]网络(树链剖分,堆)
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...
- 【BZOJ4538】[Hnoi2016]网络 整体二分+树状数组
[BZOJ4538][Hnoi2016]网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互 ...
- BZOJ 4538: [Hnoi2016]网络 [整体二分]
4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...
- 【LG3250】[HNOI2016]网络
[LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...
- 4538: [Hnoi2016]网络
4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...
- [HNOI2016]网络 树链剖分,堆
[HNOI2016]网络 LG传送门 表示乱搞比正解难想. 整体二分很好想吧. 但是为了好写快乐,我们选择三个\(\log\)的乱搞. 先树剖,线段树套堆维护区间最大值.对于一次修改,如果是插入,就把 ...
- Luogu-3250 [HNOI2016]网络
Luogu-3250 [HNOI2016]网络 题面 Luogu-3250 题解 CDQ分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...
随机推荐
- ProtoBuf - Arena
1.概述 最近看 Protocal Buffer 的源码,初次见到这个库源自陈硕的 muduo ,便打算看一看,在此做一下记录.官网文档不能访问,只能凭借代码的自己理解,查看的源码版本为 3.6.0. ...
- squid正向代理使用
环境: Squid Cache: Version 3.5.20 操作系统: centos7.6 squid安装配置 yum install -y squid systemctl start sq ...
- token 的生成杂谈
背景 很多时候我们需要用 token 来作为一些标识, 比如: 一个用户登录后的认证标识. 实现方式 md5 的方式: $v = 1; // 自己定义的 需要hash 的value 值 $key = ...
- Python之机器学习-波斯顿房价预测
目录 波士顿房价预测 导入模块 获取数据 打印数据 特征选择 散点图矩阵 关联矩阵 训练模型 可视化 波士顿房价预测 导入模块 import pandas as pd import numpy as ...
- python 开发搭建目录规范
软件目录结构规范有什么好处: 通过规范化,能够更好的控制软件结构,让程序具有更高的可读性. 项目目录组织结构如下: Foo/ # 项目名 --bin/ # 可执行文件目录 --foo # 可执行程序 ...
- Java恶搞!强制关闭电脑上的程序进程!
效果 最近写代码经常和各种进程打交道,发现了一个很有意思的黑科技. 我直接说有什么用吧,可以设置每隔多少时间检查某个程序是否在使用,如果在用,就强制关闭.比如,有的sb舍友晚上就是不睡觉,一边打游戏一 ...
- TCP传输的三次握手四次挥手策略
为了准确无误地数据送达目标处,TCP协议采用了三次握手策略.用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,它一定会向对方确认是否成功送达.握手中使用了TCP的标志:SYN和ACK 发 ...
- 如何写Java文档注释(Java Doc Comments)
本文翻译自How to Write Doc Comments for the Javadoc Tool,但是精简了一些私以为不重要的东西 本文不讨论如何使用javadoc工具自动生成文档的方法,而是主 ...
- uva10537 最短路 倒推
题意:知道了,最后需要的,那么就倒着最短路,推出去就可以了. 以最短路的方式来解决.
- 【HDOJ6118】度度熊的交易计划(费用流)
题意: 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个 ...