整体二分是个好东西!可我忘记了它QAQ其实当你知道这题可以整体二分的时候就已经不难了(个人觉得这是最难想到的一点啊)。整体二分的话,我们就可以把问题转化为是否有一条权值 \(>= k\) 的链经过某一点,这个可以通过树上差分做到 \(logn\) 的复杂度。而由于每次二分答案之后,都可以将询问和操作分成两个部分,所以是满足整体二分的性质的。

  以及自己的代码能力还有待提升啊……(;д;)

#include <bits/stdc++.h>
using namespace std;
#define lowbit(i) (i & (-i))
#define maxn 1000000
#define INF 99999999
#define CNST 20
int n, m, tot, book[maxn];
int b[maxn], id[maxn];
int C[maxn], Ans[maxn], pos[maxn];
int dfn[maxn], size[maxn], f[maxn];
int timer, cnt, ST[maxn * ][CNST];
int bit[CNST], Log[maxn * ];
map <int, int> Map; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct node
{
int opt, x, y, w, mark, id, rec;
}Q[maxn], ql[maxn], qr[maxn]; struct edge
{
int cnp, to[maxn], last[maxn], head[maxn];
edge() { cnp = ; }
void add(int u, int v)
{
to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++;
to[cnp] = u, last[cnp] = head[v], head[v] = cnp ++;
}
}E1; void Update(int x, int y)
{
if(!x) return;
for(; x <= n; x += lowbit(x)) C[x] += y;
} int Query(int x)
{
int ret = ;
for(; x; x -= lowbit(x)) ret += C[x];
return ret;
} void dfs(int u, int fa)
{
dfn[u] = ++ timer; size[u] = ; f[dfn[u]] = dfn[fa];
ST[++ cnt][] = dfn[u]; pos[u] = cnt;
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i];
if(v == fa) continue;
dfs(v, u); size[u] += size[v];
ST[++ cnt][] = dfn[u];
}
} int RMQ(int u, int v)
{
u = pos[u], v = pos[v];
if(u > v) swap(u, v);
int k = Log[v - u + ];
return min(ST[u][k], ST[v - bit[k] + ][k]);
} void Check(int l, int r, int ll, int rr)
{
if(l == r)
{
for(int i = ll; i <= rr; i ++)
if(Q[i].opt == )
Ans[Q[i].id] = l ? id[l] : -;
return;
}
if(l > r) return;
int mid = (l + r) >> , sum = ;
for(int i = ll; i <= rr; i ++)
{
int x = Q[i].x, y = Q[i].y;
if(!Q[i].opt && Q[i].rec > mid)
{
Update(dfn[x], ), Update(dfn[y], );
int K = RMQ(x, y);
Update(K, -), Update(f[K], -); sum ++;
}
else if(Q[i].opt == && Q[i].rec > mid)
{
Update(dfn[x], -), Update(dfn[y], -);
int K = RMQ(x, y);
Update(K, ), Update(f[K], ); sum --;
}
else if(Q[i].opt == )
{
int x = Query(dfn[Q[i].x] + size[Q[i].x] - ) - Query(dfn[Q[i].x] - );
if(x < sum) Q[i].mark = ;
}
}
for(int i = ll; i <= rr; i ++)
{
int x = Q[i].x, y = Q[i].y;
if(!Q[i].opt && Q[i].rec > mid && !book[Q[i].id])
{
Update(dfn[x], -), Update(dfn[y], -);
int K = RMQ(x, y);
Update(K, ), Update(f[K], );
}
}
int L = , R = ;
for(int i = ll; i <= rr; i ++)
{
if(Q[i].opt == )
{
if(Q[i].mark) Q[i].mark = , qr[++ R] = Q[i];
else ql[++ L] = Q[i];
}
else if(Q[i].rec > mid) qr[++ R] = Q[i];
else ql[++ L] = Q[i];
}
int rec = ll - , ls = , rs = ;
while(ls <= L) Q[++ rec] = ql[ls], ls ++;
while(rs <= R) Q[++ rec] = qr[rs], rs ++; Check(l, mid, ll, ll + ls - );
Check(mid + , r, ll + ls - , rr);
} void init()
{
bit[] = ; for(int i = ; i < CNST; i ++) bit[i] = bit[i - ] << ;
Log[] = -; for(int i = ; i < maxn * ; i ++) Log[i] = Log[i >> ] + ;
} int main()
{
init();
n = read(), m = read();
for(int i = ; i <= m; i ++) Ans[i] = -INF;
for(int i = ; i < n; i ++)
{
int u = read(), v = read();
E1.add(u, v);
}
dfs(, );
for(int i = ; i <= Log[cnt]; i ++)
for(int j = ; j + bit[i - ] <= cnt; j ++)
ST[j][i] = min(ST[j][i - ], ST[j + bit[i - ]][i - ]);
for(int i = ; i <= m; i ++)
{
Q[i].opt = read(); Q[i].id = i;
if(Q[i].opt == )
{
Q[i].x = read(), Q[i].y = read(), Q[i].w = read();
b[++ tot] = Q[i].w;
}
else if(Q[i].opt == )
{
int t = read(); book[t] = ;
Q[i] = Q[t], Q[i].opt = ; Q[i].id = i;
}
else if(Q[i].opt == ) Q[i].x = read();
}
sort(b + , b + + tot); int tem = ;
for(int i = ; i <= tot; i ++)
if(b[i] != b[i - ]) Map[b[i]] = ++ tem, id[tem] = b[i];
tot = tem;
for(int i = ; i <= m; i ++)
if(!Q[i].opt || Q[i].opt == ) Q[i].rec = Map[Q[i].w];
Check(, tot, , m);
for(int i = ; i <= m; i ++)
if(Ans[i] != -INF) printf("%d\n", Ans[i]);
return ;
}

【题解】HNOI2016网络的更多相关文章

  1. 【LG3250】[HNOI2016]网络

    [LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...

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

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

  3. Luogu-3250 [HNOI2016]网络

    Luogu-3250 [HNOI2016]网络 题面 Luogu-3250 题解 CDQ分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...

  4. BZOJ 4538: [Hnoi2016]网络 [整体二分]

    4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...

  5. 4538: [Hnoi2016]网络

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

  6. [HNOI2016]网络 树链剖分,堆

    [HNOI2016]网络 LG传送门 表示乱搞比正解难想. 整体二分很好想吧. 但是为了好写快乐,我们选择三个\(\log\)的乱搞. 先树剖,线段树套堆维护区间最大值.对于一次修改,如果是插入,就把 ...

  7. 题解-[HNOI2016]序列

    题解-[HNOI2016]序列 [HNOI2016]序列 给定 \(n\) 和 \(m\) 以及序列 \(a\{n\}\).有 \(m\) 次询问,每次给定区间 \([l,r]\in[1,n]\),求 ...

  8. (BZOJ4538)HNOI2016 网络

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

  9. [洛谷P3250][HNOI2016]网络

    题目大意:给定一棵树.有三种操作: $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输. $1\;x:$结束第$x$个数据传输. $2\;x:$询问不经过点$x$的数据传输中 ...

随机推荐

  1. python字符串的方法介绍

    博文取自鱼C论坛文章: http://bbs.fishc.com/forum.php?mod=viewthread&tid=38992&extra=page%3D1%26filter% ...

  2. Visual studio 2010 TFS地址解析,让团队资源管理器不再显示IP地址

    第一步: 找到名为hosts的配置文件(路径C:\Windows\System32\drivers\etc\hosts)用记事本打开并写入需要的配置,例如我用到的是TFS服务器的IP地址为192.16 ...

  3. jQuery个人总结

    选择 1. end()的使用 $('div') .find('h3') .eq(2) .html('Hello') .end() //退回到选中所有的h3元素的那一步 .eq(0) //选中第一个h3 ...

  4. Tomcat - 远程调试配置

    复制一份startup.bat,更名为“startup-debug”. 替换内容如下: call "%EXECUTABLE%" start %CMD_LINE_ARGS% 替换为 ...

  5. c++ singleton

    http://www.yolinux.com/TUTORIALS/C++Singleton.html

  6. create-react-app react-redux项目 配置模块热更新hmr

    HRM并不是create-react-app专属的,提供一篇博客介绍hrm http://chrisshepherd.me/posts/adding-hot-module-reloading-to-c ...

  7. 华硕N43sl VNP 连接问题 800 807 621

    使用VPN 创建连接,在我自己的电脑上死活连接不上,换到别人的电脑就是可以妥妥的连接. 换了几多个IP都是800错误,经过测试都不能连接.于是开始排查,把防火墙关闭,把杀毒软件关闭, 在开始命令 输入 ...

  8. 自己来编写一份 Python 脚本 第一版

    解决问题 我们已经探索了 Python 语言中的许多部分,现在我们将通过设计并编写一款程序来了解如何把这些部分组合到一起.这些程序一定是能做到一些有用的事情.这节的Python教程就是教大家方法去学习 ...

  9. POJ - 3259

    要判断是否有负的权值 #include<iostream> #include<stdio.h> #include<algorithm> #include<st ...

  10. 两种缓存淘汰算法LFU&LRU

    LRU全称是Least Recently Used,即最近最久未使用的意思. LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小.也就是说,当限定的空间已 ...