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]--] 然后 ...
随机推荐
- 网络爬虫技术Jsoup——爬到一切你想要的(转)
转自:http://blog.csdn.net/ccg_201216323/article/details/53576654 本文由我的微信公众号(bruce常)原创首发, 并同步发表到csdn博客, ...
- 应用中Token的作用
Token 的作用 Token,就是令牌,最大的特点就是随机性,不可预测.一般黑客或软件无法猜测出来. 那么,Token有什么作用?又是什么原理呢? Token一般用在两个地方: 1)防止表单重复提交 ...
- [20160711][在Windows下调用neven链接库]
相关说明 这篇文档是接前篇[20160711][neven代码移植Windows]和[20160711][VS2012配置OpenCV2.4.9]下完成,首先需要通过篇文档编译出neven动态链接库和 ...
- JavaScript八张思维导图—字符串用法
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
- github网站介绍、并使用git命令管理github(详细描述)
本章学习: 1)熟悉github网站 2)通过git命令远程管理github, 3)git命令使用ssh key密钥无需输入账号密码 1.首先我们来熟悉github网站 1.1 注册github 登录 ...
- 常用sql语句整理:mysql
## 常用sql语句整理:mysql1. 增- 增加一张表```CREATE TABLE `table_name`( ... )ENGINE=InnoDB DEFAULT CHARSET=utf8 ...
- dede列表标签list:应用大全 {dede:list}
http://syizq.blog.163.com/blog/static/435700372011616115826329/ 标签名称: list 功能说明: 表示列表模板里的分页内容列表 适用范围 ...
- Linux虚拟主机通过FTP软件创建目录时提示550 Create Directory Operation Failed
更新时间:2017-06-07 13:26:11 分享: 问题描述 通过FTP软件连接Linux虚拟主机,在尝试创建新目录时,服务器返回错误提示:550 Create Directory Oper ...
- Asp.net mvc 中Action 方法的执行(三)
[toc] 前面介绍了 Action 方法执行过程中的一些主要的组件以及方法执行过程中需要的参数的源数据的提供以及参数的绑定,那些都可以看作是 Action 方法执行前的一些必要的准备工作,接下来便将 ...
- SQL Constraints
每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束. http://www.w3school.com.cn/sql/sql_unique.asp 另外相关:@On ...