【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分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...
随机推荐
- linux中查看文件指定行的数据
http://jingyan.baidu.com/article/15622f24125872fdfdbea560.html
- 关于js事件冒泡和事件捕获
事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件.相反的,事件冒泡是自下而上的去触发事件.绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获.true,事件捕获: ...
- HDU - 4514 湫湫系列故事——设计风景线(并查集判环)
题目: 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n ...
- MongoDB中mapReduce的使用
MongoDB中mapReduce的使用 制作人:全心全意 mapReduce的功能和group by的功能类似,但比group by处理的数据量更大 使用示例: var map = function ...
- Matlab学习笔记(五)
三.矩阵运算 (一)矩阵函数和特殊矩阵 常见的矩阵处理函数 表3-1 常见的矩阵函数 函数 说明 /或\ 矩阵除法中的左除或右除,可以用于求解线性方程组 accumarray(ind,val) ...
- 初学数位DP
所谓数位dp,字面意思就是在数位上进行dp,数位的含义:一个数有个位.十位.百位.千位.等等,数的每一位就是数位. 数位DP一般应用于: 求出给定区间[A,B]内,符合条件P[i]的数 i 的个数. ...
- STM32F407 跑马灯 寄存器版 个人笔记
更多原理请参考跑马灯 库函数版 个人笔记 步骤 使能IO口时钟.配置相关寄存器寄存器RCC->AHB1ENR 初始化IO口模式.配置四个配置寄存器 GPIOx_MODER/ GPIOx_OTYP ...
- intellij idea 忽略文件不提交
文件已经纳入版本管理 如果文件已经纳入版本了,应该采用此方法 此方法主要应对文件已经纳入版本管理,但不想再提交,比如,不小心提交的eclipse.intellij的文件,以后不想再提交了,这种就通过v ...
- HDU1241&POJ2386 dfs简单题
2道题目都差不多,就是问和相邻所有点都有相同数据相连的作为一个联通快,问有多少个连通块 因为最近对搜索题目很是畏惧,总是需要看别人代码才能上手,就先拿这两道简单的dfs题目来练练手,顺便理一理dfs的 ...
- 2017 CCPC 杭州 HDU6265B 积性函数
题目链接 http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf B题 数论题 h(n)=∑ d|n φ(d) × ...