【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述
输入
输出
样例输入
5 5
5 1 2 3 4
3 1
2 1
4 3
5 3
2 4 5
0 1 2
2 2 3
2 1 4
3 3 5
样例输出
3
2
2
invalid request!
题解
倍增LCA+dfs序+树状数组+主席树
维护一个dfs入栈出栈序,建立主席树,入栈位置将权值位置+1,出栈位置将权值位置-1.。
对于每个询问,转化为x->lca和y->lca的两条链,进而转化为4条路径:1~x + 1~y - 1~lca - 1~fa[lca]。
由于题目带修改,所以需要使用树状数组维护主席树的“前缀和”。然后就可以无脑码了。
需要注意的一点是本题卡空间,所以主席树的插入过程不能每次都新建节点,如果有节点就修改,没有再添加。
- #include <cstdio>
- #include <algorithm>
- #define N 80010
- using namespace std;
- int w[N] , head[N] , to[N << 1] , next[N << 1] , cnt , fa[N][18] , deep[N] , log[N] , lp[N] , rp[N] , num;
- int ls[N * 200] , rs[N * 200] , si[N * 200] , root[N << 1] , tot , A[40] , B[40] , C[40] , D[40] , ta , tb , tc , td;
- int v[N << 1] , tv , vk[N] , vx[N] , vy[N];
- void add(int x , int y)
- {
- to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
- }
- void dfs(int x)
- {
- int i;
- lp[x] = ++num;
- for(i = 1 ; (1 << i) <= deep[x] ; i ++ ) fa[x][i] = fa[fa[x][i - 1]][i - 1];
- for(i = head[x] ; i ; i = next[i])
- if(to[i] != fa[x][0])
- fa[to[i]][0] = x , deep[to[i]] = deep[x] + 1 , dfs(to[i]);
- rp[x] = ++num;
- }
- int lca(int x , int y)
- {
- int i;
- if(deep[x] < deep[y]) swap(x , y);
- for(i = log[deep[x] - deep[y]] ; ~i ; i -- )
- if(deep[x] - deep[y] >= (1 << i))
- x = fa[x][i];
- if(x == y) return x;
- for(i = log[deep[x]] ; ~i ; i -- )
- if(deep[x] >= (1 << i) && fa[x][i] != fa[y][i])
- x = fa[x][i] , y = fa[y][i];
- return fa[x][0];
- }
- void update(int p , int a , int l , int r , int &x)
- {
- if(!x) x = ++tot;
- si[x] += a;
- if(l == r) return;
- int mid = (l + r) >> 1;
- if(p <= mid) update(p , a , l , mid , ls[x]);
- else update(p , a , mid + 1 , r , rs[x]);
- }
- int query(int k , int l , int r)
- {
- if(l == r) return l;
- int mid = (l + r) >> 1 , sum = 0 , i;
- for(i = 1 ; i <= ta ; i ++ ) sum += si[rs[A[i]]];
- for(i = 1 ; i <= tb ; i ++ ) sum += si[rs[B[i]]];
- for(i = 1 ; i <= tc ; i ++ ) sum -= si[rs[C[i]]];
- for(i = 1 ; i <= td ; i ++ ) sum -= si[rs[D[i]]];
- if(k <= sum)
- {
- for(i = 1 ; i <= ta ; i ++ ) A[i] = rs[A[i]];
- for(i = 1 ; i <= tb ; i ++ ) B[i] = rs[B[i]];
- for(i = 1 ; i <= tc ; i ++ ) C[i] = rs[C[i]];
- for(i = 1 ; i <= td ; i ++ ) D[i] = rs[D[i]];
- return query(k , mid + 1 , r);
- }
- else
- {
- for(i = 1 ; i <= ta ; i ++ ) A[i] = ls[A[i]];
- for(i = 1 ; i <= tb ; i ++ ) B[i] = ls[B[i]];
- for(i = 1 ; i <= tc ; i ++ ) C[i] = ls[C[i]];
- for(i = 1 ; i <= td ; i ++ ) D[i] = ls[D[i]];
- return query(k - sum , l , mid);
- }
- }
- int main()
- {
- int n , q , i , j , x , y , f;
- scanf("%d%d" , &n , &q);
- for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &w[i]) , v[++tv] = w[i];
- for(i = 2 ; i <= n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x) , log[i] = log[i >> 1] + 1;
- dfs(1);
- for(i = 1 ; i <= q ; i ++ )
- {
- scanf("%d%d%d" , &vk[i] , &vx[i] , &vy[i]);
- if(!vk[i]) v[++tv] = vy[i];
- }
- sort(v + 1 , v + tv + 1);
- for(tv = 0 , i = 1 ; i <= n + q ; i ++ )
- if(v[i] != v[i - 1])
- v[++tv] = v[i];
- for(i = 1 ; i <= n ; i ++ )
- {
- w[i] = lower_bound(v + 1 , v + tv + 1 , w[i]) - v;
- for(j = lp[i] ; j <= num ; j += j & -j) update(w[i] , 1 , 1 , tv , root[j]);
- for(j = rp[i] ; j <= num ; j += j & -j) update(w[i] , -1 , 1 , tv , root[j]);
- }
- for(i = 1 ; i <= q ; i ++ )
- {
- if(vk[i])
- {
- f = lca(vx[i] , vy[i]);
- if(deep[vx[i]] + deep[vy[i]] - 2 * deep[f] + 1 < vk[i]) puts("invalid request!");
- else
- {
- ta = tb = tc = td = 0;
- for(j = lp[vx[i]] ; j ; j -= j & -j) A[++ta] = root[j];
- for(j = lp[vy[i]] ; j ; j -= j & -j) B[++tb] = root[j];
- for(j = lp[f] ; j ; j -= j & -j) C[++tc] = root[j];
- for(j = lp[fa[f][0]] ; j ; j -= j & -j) D[++td] = root[j];
- printf("%d\n" , v[query(vk[i] , 1 , tv)]);
- }
- }
- else
- {
- vy[i] = lower_bound(v + 1 , v + tv + 1 , vy[i]) - v;
- for(j = lp[vx[i]] ; j <= num ; j += j & -j) update(w[vx[i]] , -1 , 1 , tv , root[j]) , update(vy[i] , 1 , 1 , tv , root[j]);
- for(j = rp[vx[i]] ; j <= num ; j += j & -j) update(w[vx[i]] , 1 , 1 , tv , root[j]) , update(vy[i] , -1 , 1 , tv , root[j]);
- w[vx[i]] = vy[i];
- }
- }
- return 0;
- }
【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树的更多相关文章
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
- [BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- [BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...
- Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)
Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- BZOJ1146[CTSC2008]网络管理——出栈入栈序+树状数组套主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条 ...
- 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)
传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...
- 【bzoj2819】Nim(dfs序+树状数组/线段树)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2819 首先根据SG定理,可得若每堆石子数量的异或值为0,则后手必胜,反之先手必胜.于是 ...
- POJ3321[苹果树] 树状数组/线段树 + dfs序
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions:39452 Accepted: 11694 Descr ...
随机推荐
- Mybatis generator(复制粘贴完成)
命令行模式 1.java -jar mybatis-generator-core-x.x.x.jar -configfile generatorConfig.xml 2.Maven plugin(my ...
- java设计模式——单例模式(三)
容器单例模式 之前学习Structs2,Spring框架时,经常会听到单例,多例.虽然这与单例模式不太一样,但是都很类似.在程序运行的时候,就加载所有的实例,然后用的时候直接取出 看下面代码: /** ...
- 获取Bing每日壁纸用作首屏大图
获取Bing每日壁纸用作首屏大图 Bing 搜索每天都会更换一张精美的图片作为壁纸,除了特殊时候不太好看外(比如春节那几天),没多大问题.移动端还有上每日故事,与图片现配.现在我的博客首屏图片就是Bi ...
- ARC机制中的Strong和weak
什么是ARC Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化.ARC是新的LLVM 3.0编译 ...
- c语言中--typeof--关键字用法
C语言中 typeof 关键字是用来定义变量数据类型的.在linux内核源代码中广泛使用. 下面是Linux内核源代码中一个关于typeof实例: #define min(x, y) ({ \ typ ...
- 洛谷P1049装箱问题
一句话刚刚的题会了,这题能不会么. #include<bits/stdc++.h> using namespace std; int main(){ int n,m; cin>> ...
- 三十二、MySQL 导出数据
MySQL 导出数据 MySQL中你可以使用SELECT...INTO OUTFILE语句来简单的导出数据到文本文件上. 使用 SELECT ... INTO OUTFILE 语句导出数据 以下实例中 ...
- Linux监控一之Nagios的安装与配置
一.Nagios简介 Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报 ...
- PhotoSwipe图片展示插件
这个插件相当棒!功能也很强大,可以自行体会. 官方网址:http://www.photoswipe.com/ github地址:https://github.com/codecomputerlove/ ...
- Python基础:条件与循环
条件语句 除了 boolean 类型的数据,条件判断最好是显性的 if i != 0: ... 而不是只写出变量名: if i: ... For循环与While循环 通常来说,如果你只是遍历一个已知的 ...