P4175 [CTSC2008]网络管理

给定一棵有nnn个节点的树,点有点权,有两种操作:① 修改某个点的点权,② 查询两点路径间的点权第kkk大。

给定u,vu, vu,v,选定111号节点为根节点,设inf(x)inf(x)inf(x)表示从根节点到点xxx的信息,两点间的信息可以描述为inf(u)+inf(v)−inf(lca(u,v))−fa(inf(lca(u,v)))inf(u) + inf(v) - inf(lca(u, v)) - fa(inf(lca(u, v)))inf(u)+inf(v)−inf(lca(u,v))−fa(inf(lca(u,v))),

由此我们可以把树上每个点拆成[l,r,x][l, r, x][l,r,x],lll为这个点进入dfsdfsdfs的dfsdfsdfs序,rrr为这个点走出dfsdfsdfs的dfsdfsdfs序,

我们要查找inf(u)inf(u)inf(u)上的信息就只要查找有多少个[l,r,x][l, r, x][l,r,x]满足l≤dfn(u)≤rl \leq dfn(u) \leq rl≤dfn(u)≤r,树状数组区间更新,单点查询就好了。

对于每个询问可以写成u,v,lca(u,v),fa(lca(u,v))u, v, lca(u, v), fa(lca(u, v))u,v,lca(u,v),fa(lca(u,v)),我们把树上的点,修改操作,询问操作放到数组中整体二分一下即可。

(感觉代码好像比树套树好写一点点……)

#include <bits/stdc++.h>using namespace std;const int N = 2e5 + 10;int head[N], to[N], nex[N], cnt = 1;int a[N], ans[N], n, m;int son[N], fa[N], l[N], dep[N], r[N], sz[N], top[N], sum[N], tot;struct Res {int l, r, f, ff, x, id, type;
}q[N], q1[N], q2[N];void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs1(int rt, int f) {dep[rt] = dep[f] + 1, fa[rt] = f, sz[rt] = 1, l[rt] = ++tot;for (int i = head[rt]; i; i = nex[i]) {if (to[i] == f) {continue;}dfs1(to[i], rt);sz[rt] += sz[to[i]];if (!son[rt] || sz[to[i]] > sz[son[rt]]) {son[rt] = to[i];}}r[rt] = tot;
}void dfs2(int rt, int tp) {top[rt] = tp;if (!son[rt]) {return ;}dfs2(son[rt], tp);for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa[rt] || to[i] == son[rt]) {continue;}dfs2(to[i], to[i]);}
}int lca(int x, int y) {while (top[x] != top[y]) {if (dep[top[x]] < dep[top[y]]) {swap(x, y);}x = fa[top[x]];}return dep[x] <= dep[y] ? x : y;
}inline int lowbit(int x) {return x & (-x);
}void update(int rt, int v) {while (rt <= N) {sum[rt] += v;rt += lowbit(rt);}
}int query(int rt) {int ans = 0;while (rt) {ans += sum[rt];rt -= lowbit(rt);}return ans;
}void solve(int l, int r, int L, int R) {if (l > r || L > R) {return ;}if (l == r) {for (int i = L; i <= R; i++) {if (q[i].type == 2) {ans[q[i].id] = l;}}return ;}int mid = l + r >> 1, cnt1 = 0, cnt2 = 0;for (int i = L; i <= R; i++) {if (q[i].type == 1) {if (q[i].x <= mid) {int l = q[i].l, r = q[i].r;update(l, q[i].id), update(r + 1, -q[i].id);q1[++cnt1] = q[i];}else {q2[++cnt2] = q[i];}}else {int cur = query(q[i].l) + query(q[i].r) - query(q[i].f) - query(q[i].ff);if (cur >= q[i].x) {q1[++cnt1] = q[i];}else {q[i].x -= cur;q2[++cnt2] = q[i];}}}for (int i = 1; i <= cnt1; i++) {if (q1[i].type == 1) {int l = q1[i].l, r = q1[i].r;update(l, -q1[i].id), update(r + 1, q1[i].id);}}for (int i = 1; i <= cnt1; i++) {q[L + i - 1] = q1[i];}for (int i = 1; i <= cnt2; i++) {q[L + cnt1 + i - 1] = q2[i];}solve(l, mid, L, L + cnt1 - 1), solve(mid + 1, r, L + cnt1, R);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d %d", &n, &m);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}for (int i = 1, x, y; i < n; i++) {scanf("%d %d", &x, &y);add(x, y);add(y, x);}dfs1(1, 0);dfs2(1, 1);for (int i = 1; i <= m; i++) {ans[i] = 1000000000;}int num = 0;for (int i = 1; i <= n; i++) {q[++num] = {l[i], r[i], 0, 0, a[i], 1, 1};}for (int i = 1, k, x, y; i <= m; i++) {scanf("%d %d %d", &k, &x, &y);if (!k) {q[++num] = {l[x], r[x], 0, 0, a[x], -1, 1};a[x] = y;q[++num] = {l[x], r[x], 0, 0, a[x], 1, 1};}else {int f = lca(x, y), ff = fa[f], sum = dep[x] + dep[y] - dep[f] - dep[ff];if (sum >= k) {q[++num] = {l[x], l[y], l[f], l[ff], sum - k + 1, i, 2};}else {ans[i] = -1;}}}solve(0, 100000000, 1, num);for (int i = 1; i <= m; i++) {if (ans[i] != 1000000000) {if (ans[i] == -1) {puts("invalid request!");}else {printf("%d\n", ans[i]);}}}return 0;
}

P4175 [CTSC2008]网络管理(整体二分)相关推荐

  1. P4175 [CTSC2008]网络管理 (动态树上第k大)

    题目链接: P4175 [CTSC2008]网络管理 大致题意 给定一棵有nnn个节点的树, 节点上有权值wiw_iwi​. 有mmm次操作. 0 a b 表示把节点aaa的权值修改为bbb. 即: ...

  2. 【BZOJ1146】【CTSC2008】网络管理 [整体二分]

    网络管理 Time Limit: 50 Sec  Memory Limit: 162 MB [Submit][Status][Discuss] Description M公司是一个非常庞大的跨国公司, ...

  3. 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理

    令人抓狂的整体二分题.根本原因还是我太菜了. 在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了--不过还是太慢. 题目传送门:洛谷P4175. 题意简述: 一棵 \(n\) 个结点的树, ...

  4. 【bzoj1146】 [CTSC2008]网络管理Network【树链剖分+树套树+二分 线段树套Treap】

    1146: [CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公 ...

  5. 【BZOJ1146】网络管理,整体二分

    传送门 好久没更新题解了,感觉这道题思路不难,但做法挺多的,我大概能想到四种做法,如果有神犇还有其他好方法请在下方评论 1.树链剖分,每条重链维护一颗平衡树 修改直接做logn\log n 查询时二分 ...

  6. SP3946 MKTHNUM - K-th Number(整体二分)

    思路 整体二分的板子题,没什么思路好说 代码 #include <cstdio> #include <algorithm> #include <cstring> u ...

  7. BZOJ2738 矩阵乘法 【整体二分 + BIT】

    题目链接 BZOJ2738 题解 将矩阵中的位置取出来按权值排序 直接整体二分 + 二维BIT即可 #include<algorithm> #include<iostream> ...

  8. [bzoj2527][Poi2011]Meteors_整体二分_树状数组

    Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...

  9. 【BZOJ2738】矩阵乘法 [整体二分][树状数组]

    矩阵乘法 Time Limit: 20 Sec  Memory Limit: 256 MB [Submit][Status][Discuss] Description 给你一个N*N的矩阵,不用算矩阵 ...

最新文章

  1. Linux进程与线程的区别
  2. ASP.NET Core文件上传与下载(多种上传方式)
  3. [Leedcode][JAVA][第983题][最低票价][动态规划]
  4. socket connect java_网络编程 – 为什么Java的socket.connect()消耗100%的cpu资源?
  5. 统计mysql binlog日志总大小
  6. PHP 循环时间控制缓冲方法
  7. Struts2 Result 类型和对应的用法详解 2
  8. java jtree怎么初始化,java – 如何设置JTree“ctrl”选择模式始终启用
  9. DevOps-2-从凤凰项目谈起
  10. 富士通服务器irmc账号密码,PRIMERGY TX1330 M2 E3-1200 V5单路 Fujitsu富士通立式服务器...
  11. vue 倒计时 插件_vue倒计时组件
  12. Google图片url搜索测试
  13. Cocoa-Cocoa框架
  14. 5.视频监控 - 摄像头接口
  15. 禾穗HERS | 不结婚就不孝?催婚季必备三招快学起来!
  16. Qt Mtd调用方式
  17. 22222222222222222222222
  18. java基础之数据类型
  19. 【Aviator】(二)应用实战
  20. 艾诚专访崔晓波:为何用数据才能洞察这个世界?

热门文章

  1. android auto answer,Incoming call auto answer in android 4.0.3
  2. linux系统多网口聚合配置,Linux网卡聚合linux多网卡绑定聚合之bond模式的原理是什么...
  3. 机器学习模型 知乎_机器学习-模型选择与评价
  4. 06-广度优先搜索:图、队列
  5. 学过物理的人才能看懂的笑话,你能看明白几个?
  6. 减肥瘦不下来的原因找到了
  7. android 横向stepview,Android 流程指示器 StepView
  8. python pp模块_Python模块--Pexpect
  9. 随机加解密java_JAVA随机数生成 Math.random和java.util.Random使用简介
  10. mysql从多个表查询数据类型_MySQL 之 多表查询