4538: [Hnoi2016]网络

题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值


考虑二分

整体二分最大权值,如果\(k \in [mid+1,r]\)中的路径有不经过x的,那么这个询问的答案在\([mid+1,r]\)中

链修改,点查询\(\rightarrow\)点修改,子树查询,方法是\(u,v +1\ ;\ lca,fa[lca] -1\)

用树状数组就可以完成

这里的整体二分不需要对每个询问保存当前贡献,因为每次只需要考虑一段的贡献

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define fir first
#define sec second
const int N=2e5+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
} int n, Q, id[N], mp[N], t1[N], t2[N], ans[N];
struct meow{int op, u, v, k, t, x;} q[N]; struct edge{int v, ne;}e[N-1];
int cnt=1, h[N];
inline void ins(int u, int v) {
e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
e[++cnt]=(edge){u, h[v]}; h[v]=cnt;
}
namespace tr {
pair<int, int> dfn[N];
int fa[N], deep[N], dfc, tot, pos[N], f[N<<1][18];
void dfs(int u) {
dfn[u].fir = ++dfc;
f[++tot][0] = u;
pos[u] = tot;
for(int i=h[u];i;i=e[i].ne)
if(e[i].v != fa[u]) {
fa[e[i].v] = u;
deep[e[i].v] = deep[u]+1;
dfs(e[i].v);
f[++tot][0] = u;
}
dfn[u].sec = dfc;
}
int log[N];
inline int min(int x, int y) {return deep[x] < deep[y] ? x : y;}
void init() {
dfs(1);
//for(int i=1; i<=tot; i++) printf("%d ", f[i][0]); puts("");
for(int j=1; j<=17; j++)
for(int i=1; i+(1<<j)-1<=tot; i++)
f[i][j] = min(f[i][j-1], f[i+(1<<(j-1))][j-1]);// printf("f %d %d %d\n",i,j,f[i][j]); log[1]=0; for(int i=2; i<=tot; i++) log[i] = log[i>>1]+1;
}
inline int lca(int x, int y) {
x = pos[x], y = pos[y]; if(x>y) swap(x, y);
int t = log[y-x+1];
return min(f[x][t], f[y-(1<<t)+1][t]);
}
} using tr::lca; using tr::fa; using tr::dfn; namespace bit {
int c[N], T, t[N];
inline void ini() {T++;}
inline void add(int p, int v) {
for(; p<=n; p+=p&-p) {
if(t[p] == T) c[p] += v;
else t[p] = T, c[p] = v;
}
}
inline int sum(int p) {
int ans=0;
for(; p; p-=p&-p) if(t[p] == T) ans += c[p];
return ans;
}
inline int sum(int l, int r) {return sum(r) - sum(l-1);}
inline void cha(int id, int flag) {
int u=q[id].u, v=q[id].v, p=lca(u, v); //printf("uvp %d %d %d\n", u, v, p);
add(dfn[u].fir, flag); add(dfn[v].fir, flag);
add(dfn[p].fir, -flag); if(fa[p]) add(dfn[ fa[p] ].fir, -flag);
}
} using bit::sum; using bit::cha; void cdq(int l, int r, int ql, int qr) { //printf("cdq [%d, %d] %d %d\n",l, r, ql, qr);
if(l==r) {
for(int i=ql; i<=qr; i++) if(q[id[i]].op == 3) ans[ id[i] ] = l;
return;
} int mid = (l+r)>>1, p1=0, p2=0; //printf("mid %d\n", mid);
bit::ini();
int now=0;
for(int i=ql; i<=qr; i++) {
int _=i; i=id[i]; //printf("i-------- %d %d %d\n",_,i, q[i].op);
if(q[i].op == 1) { //printf("k %d\n", q[i].k);
if(q[i].k > mid) cha(i, 1), now++, t2[++p2] = i;
else t1[++p1] = i;
} else if(q[i].op == 2) {
if(q[ q[i].t ].k > mid) cha(q[i].t, -1), now--, t2[++p2] = i;
else t1[++p1] = i;
} else {
int x = q[i].x, cnt = sum(dfn[x].fir, dfn[x].sec); //printf("hi que %d %d %d\n", x, cnt, now);
if(cnt < now) t2[++p2] = i;
else t1[++p1] = i;
}
i=_;
}
for(int i=1; i<=p1; i++) id[ql+i-1] = t1[i];
for(int i=1; i<=p2; i++) id[ql+p1+i-1] = t2[i];
cdq(l, mid, ql, ql+p1-1); cdq(mid+1, r, ql+p1, qr);
} int main() {
//freopen("in", "r", stdin);
freopen("network_tenderRun.in", "r", stdin);
freopen("network_tenderRun.out", "w", stdout);
n=read(); Q=read();
for(int i=1; i<n; i++) ins(read(), read());
for(int i=1; i<=Q; i++) {
q[i].op = read()+1;
if(q[i].op == 1) q[i].u=read(), q[i].v=read(), mp[++mp[0]] = q[i].k=read();
else if(q[i].op == 2) q[i].t=read();
else q[i].x=read();
id[i]=i;
}
sort(mp+1, mp+mp[0]+1); mp[0] = unique(mp+1, mp+mp[0]+1) - mp - 1;
for(int i=1; i<=Q; i++) if(q[i].op == 1) q[i].k = lower_bound(mp+1, mp+mp[0]+1, q[i].k) - mp;// printf("k %d %d\n", i, q[i].k);
tr::init();
//for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) printf("lca %d %d %d\n",i,j,lca(i, j));
cdq(0, mp[0], 1, Q);
for(int i=1; i<=Q; i++) if(q[i].op == 3) printf("%d\n", ans[i] ? mp[ans[i]] : -1);
}

BZOJ 4538: [Hnoi2016]网络 [整体二分]的更多相关文章

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

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

  2. 洛咕P3250 [HNOI2016]网络 整体二分

    这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...

  3. bzoj 4538: [Hnoi2016]网络

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

  4. 4538: [Hnoi2016]网络

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

  5. BZOJ.2527.[POI2011]MET-Meteors(整体二分)

    题目链接 BZOJ 洛谷 每个国家的答案可以二分+求前缀和,于是可以想到整体二分. 在每次Solve()中要更新所有国家得到的值,不同位置的空间站对应不同国家比较麻烦. 注意到每次Solve()其国家 ...

  6. BZOJ.2738.矩阵乘法(整体二分 二维树状数组)

    题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...

  7. bzoj 2527: [Poi2011]Meteors 整体二分

    给每个国家建一个链表,这样分治过程中的复杂度就和序列长度线形相关了,无脑套整体二分就可以. (最坑的地方是如果所有位置都是一个国家,那么它的样本个数会爆longlong!!被这个坑了一次,大于p[i] ...

  8. BZOJ 2738: 矩阵乘法 [整体二分]

    给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...

  9. luogu3250 网络 (整体二分+树上差分+树状数组)

    首先整体二分,问题变成是否存在经过一个点的满足条件的路径 那么我对于每个路径(a,b,lca),在树状数组的dfn[a]++,dfn[b]++,dfn[lca]--,dfn[fa[lca]--] 然后 ...

随机推荐

  1. android动画源码合集、动态主题框架、社交app源码等

    Android精选源码 仿MIUI果冻视图-BouncingJellyView   一个快速易用的动态主题框架   android动画效果集合源码   android使用Kotlin开发的Dribbb ...

  2. [国嵌攻略][070-095][Linux编程函数手册]

    第1类 时间编程类 1.1 获取日历时间 1.1.1 函数名 time 1.1.2 函数原形 time_t time(time_t *t) 1.1.3 函数功能 返回日历时间 1.1.4 所属头文件 ...

  3. 安装Ruby、Sass与Compass

    sass基于Ruby语言开发而成,因此安装sass前需要安装Ruby.(注:mac下自带Ruby无需在安装Ruby!) window下安装SASS首先需要安装Ruby,先从官网下载Ruby并安装.安装 ...

  4. java实现单链表常见操作

    一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...

  5. ubuntu 下 apt /apt-get command not found 命令找不到

    简介:apt 命令在ubuntu下找不到.(针对云平台,等可联网的ubuntu  如果是虚拟机,请确认能否联网 (如是虚拟机且不能联网请参考其他文章,大致方向是先挂载系统镜像再安装)) (ps:一般的 ...

  6. 数据库01创建表和DML语言

    楼主用的数据库时mysql,用的时navacat for mysql. 数据库层面: 1.显示所有数据库 show databases; 2.创建数据库,名字叫lyh,编码为utf-8 create ...

  7. 邓_tp_笔记

    <?phpnamespace app\teacher\controller;use think\Db;use app\common\model\Classcourse;use app\commo ...

  8. ASP.net core 2.0.0 中 asp.net identity 2.0.0 的基本使用(四)—用户注册

    修改用户注册 1.修改用户名注册规则. 打开Controllers目录下的AccountController.cs. 在控制器中找到 public async Task<IActionResul ...

  9. error: stray '\357' in program编程出错的总结

    错误: 编译报错:error: stray '\357' in program 原因:在程序中打入了全角字符   具体分析产生原因: 在编程中,由于打字的快速,按下ctrl键后紧接着按下了space键 ...

  10. cookie sessionStorage localStorage 之间的关系

    先说一个cookie 因为HTTP是无状态的 所以cookie诞生 用于保存会话信息 大小 4096b 一般在4095b以内 数量限制 20 -50 根据浏览器不同 操作的是一个字符串 可以设置参数 ...