BZOJ 4538: [Hnoi2016]网络 [整体二分]
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]网络 [整体二分]的更多相关文章
- 【BZOJ4538】[Hnoi2016]网络 整体二分+树状数组
[BZOJ4538][Hnoi2016]网络 Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互 ...
- 洛咕P3250 [HNOI2016]网络 整体二分
这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...
- bzoj 4538: [Hnoi2016]网络
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有服 ...
- 4538: [Hnoi2016]网络
4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...
- BZOJ.2527.[POI2011]MET-Meteors(整体二分)
题目链接 BZOJ 洛谷 每个国家的答案可以二分+求前缀和,于是可以想到整体二分. 在每次Solve()中要更新所有国家得到的值,不同位置的空间站对应不同国家比较麻烦. 注意到每次Solve()其国家 ...
- BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...
- bzoj 2527: [Poi2011]Meteors 整体二分
给每个国家建一个链表,这样分治过程中的复杂度就和序列长度线形相关了,无脑套整体二分就可以. (最坑的地方是如果所有位置都是一个国家,那么它的样本个数会爆longlong!!被这个坑了一次,大于p[i] ...
- BZOJ 2738: 矩阵乘法 [整体二分]
给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...
- luogu3250 网络 (整体二分+树上差分+树状数组)
首先整体二分,问题变成是否存在经过一个点的满足条件的路径 那么我对于每个路径(a,b,lca),在树状数组的dfn[a]++,dfn[b]++,dfn[lca]--,dfn[fa[lca]--] 然后 ...
随机推荐
- 使用 SVG 和 JS 创建一个由星形变心形的动画
序言:首先,这是一篇学习 SVG 及 JS 动画不可多得的优秀文章.我非常喜欢 Ana Tudor 写的教程.在她的教程中有大量使用 SVG 制作的图解以及实时交互 DEMO,可以说教程的所有细枝末节 ...
- RabbitMQ 使用demo
1.新建一个控制台应用程序:如图 2.代码如下: using RabbitMQ.Client;using RabbitMQ.Client.Events;using System;using Syste ...
- 常用Windows DOS命令项目部署经常用到
img { max-width: 100% } 前两天部署.netcore项目,首先是生产环境域名访问不了,再到.netcore项目IIS部署502.5,在到莫名其妙的500,在排查项目部署问题的时候 ...
- 审计日志中的AOP
审计跟踪(也称为审核日志)是一个安全相关的时间顺序记录,记录这些记录的目的是为已经影响在任何时候的详细操作,提供程序运行的证明文件记录.源或事件 MVC 自定义一个过滤器 public class A ...
- 任务驱动 搭建SSM开发环境
本篇主要阐述(IntelliJ IDEA + Maven + Spring + Spring MVC + Mybatis)搭建 为什么想要搭建ssm? 近期正好自己有一个小的点子要实现,恰好这学期开了 ...
- UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现
UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现 测试数据 java代码 package com.hzf.spark.study; import ...
- mdb文件怎么打开
(一)mdb格式的文件可以用MS Access打开编辑,也可以用Excel打开只能浏览. (二)mdb是什么文件格式 就像word的doc文件格式,mdb文件格式是Access数据库文件,微软Off ...
- css cursor属性-显示的光标的类型(形状)的用法和定义
在网页布局的时候,在特定的地方,光标形状各有区别.这个时候,就需要用到css的cursor属性.根据自身需要选择设置鼠标指针样式. 定义和用法 cursor 属性规定要显示的光标的类型(形状). 该属 ...
- asp.net -mvc框架复习(9)-实现用户登录控制器和视图的编写并调试
1.编写控制器 三个步骤: [1]获取数据 [2]业务处理 [3]返回数据 using System;using System.Collections.Generic;using System.Lin ...
- 《HelloGitHub》第 22 期
公告 年前最后一期,下次就是年后了,老时间 每月的 28 号,年后见- <HelloGitHub>第 22 期 兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 G ...