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]--] 然后 ...
随机推荐
- RegExp对象的三个方法
RegExp 对象有 3 个方法:test().exec() 以及 compile(). test( ) test()方法检索字符串中的指定值.返回值是true或false. 例子: 因为字符 ...
- Mybatis中是否需要依赖配置文件的名称要和mapper接口的名称一致 params错误
一:当核心配置文件mapper标签下以resource形式指向依赖配置文件时,不需要 这样就可以加载到其相应的依赖配置文件通过namespace找到其相应的方法 二:如果mapper标签下以packa ...
- Java | 原来 try 还可以这样用啊?!
本文首发于 http://youngzy.com/ 习惯了这样的try: try { } catch (Exception e) { } 看到了这样的try,觉得有点神奇: try(...) { } ...
- WEBZIP为什么打不开网页
先试三个办法 一.打开IE,点工具,点internet选项,点高级,点恢复默认设置,点保存,退出,重新打开IE 二.打开IE,刷新五次以上 三.打开IE,点工具,点internet选项,点删除文件,点 ...
- php网站在服务器上邮件发送不了,在本地可以
标签: php邮箱 2015-11-27 13:58 879人阅读 评论(0) 收藏 举报 分类: php(2) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在做phpmailer发送邮 ...
- cobol
过程部的语句一般从B区开始书写. ACCEPT A,B (x) DISPLAY T1,T2.(O)显示在一行上 DISPLAY T1 DISPLAY T2 (O)显示在两行上 read ...
- C#总结(四)调用C++动态库
由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...
- 深入浅出讲解:php的socket通信[转]
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1. 什么是TCP/IP.UDP?2. Sock ...
- javaweb后台转码
为什么需要转码? 客户端向服务器发送请求的四种情况:1.URL方式直接访问;2.页面链接(属于get请求);3.表单get提交;4.表单post提交 1.url(url和页面链接):各大浏览器.各个操 ...
- linkin大话数据结构--字符串,数组,list之间的互转
在实际开发中,我们经常会用到字符串,字符数组,字符list,当然也会不可避免的进行这3者之间的互相转换. 在使用到Apache和Google下的common包,可以这样子实现: package tz. ...