bzoj 3551
按照困难度升序排序
Kruskal重构树
这样一来一个点的子树中的所有困难值都小于改点的困难值
对于每次询问
倍增找出困难值最大且小于x的点
该点的子树中的第k大就是询问的答案
主席书维护区间k大
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring> using namespace std;
const int N = 1e5 + , M = 2e5 + ; int n, m, Q;
int A[N << ], high[N << ], val[N << ];
struct Node {
int u, v, hard;
} Edge[M * ];
struct Node_ {
int v, nxt;
} G[M * ];
int fa[N << ];
int Root[N << ];
int W[M * ];
int head[N << ];
int Lson[M * ], Rson[M * ];
int now;
int tree[N << ], bef[N << ], lst[N << ], rst[N << ], Tree;
int N_;
int f[N << ][];
int Ans;
int Segjs;
int impjs; #define gc getchar()
inline int read() {
int x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} inline bool Cmp(Node a, Node b) {
return a.hard < b.hard;
} int Get(int x) {
return fa[x] == x ? x : fa[x] = Get(fa[x]);
} inline void Add(int u, int v) {
G[++ now].v = v;
G[now].nxt = head[u];
head[u] = now;
} inline void Pre() {
for(int i = ; i <= ; i ++) for(int j = ; j <= n * - ; j ++) f[j][i] = f[f[j][i - ]][i - ];
} inline void Fill(int x, int y) {
Lson[x] = Lson[y], Rson[x] = Rson[y], W[x] = W[y];
} inline int Imp_find(int u, int x) {
for(int i = ; i >= ; i --) if(f[u][i] && val[f[u][i]] <= x) u = f[u][i];
return u;
} inline void Kruskal() {
sort(Edge + , Edge + m + , Cmp);
impjs = n;
for(int i = ; i <= n * ; i ++) fa[i] = i;
for(int i = ; i <= n * ; i ++) head[i] = -;
for(int i = ; i <= m; i ++) {
int fau = Get(Edge[i].u), fav = Get(Edge[i].v);
if(fau != fav) {
impjs ++;
val[impjs] = Edge[i].hard;
fa[fau] = fa[fav] = impjs;
Add(impjs, fau), Add(fau, impjs), Add(impjs, fav), Add(fav, impjs);
}
if(impjs == n * - ) break;
}
} void Dfs(int u, int fa) {
if(u <= n) {
lst[u] = rst[u] = ++ Tree;
bef[Tree] = u;
}
else lst[u] = n;
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(v == fa) continue;
f[v][] = u;
Dfs(v, u);
rst[u] = max(rst[u], rst[v]), lst[u] = min(lst[u], lst[v]);
}
} void Insert(int &rt, int l, int r, int x) {
Fill(++ Segjs, rt);
rt = Segjs;
W[rt] ++;
if(l == r) return ;
int mid = (l + r) >> ;
if(x <= mid) Insert(Lson[rt], l, mid, x);
else Insert(Rson[rt], mid + , r, x);
} void Sec_A(int jd1, int jd2, int l, int r, int k) {
if(l == r) {Ans = l; return ;}
if(W[jd2] - W[jd1] < k) {Ans = -; return ;}
int mid = (l + r) >> ;
if(W[Rson[jd2]] - W[Rson[jd1]] >= k) Sec_A(Rson[jd1], Rson[jd2], mid + , r, k);
else Sec_A(Lson[jd1], Lson[jd2], l, mid, k - (W[Rson[jd2]] - W[Rson[jd1]]));
} int main() {
n = read(), m = read(), Q = read();
for(int i = ; i <= n; i ++)
A[i] = read(), high[i] = A[i];
for(int i = ; i <= m; i ++) {
int a = read(), b = read(), c = read();
Edge[i] = (Node) {a, b, c};
}
sort(A + , A + n + );
int a = unique(A + , A + n + ) - A - ;
for(int i = ; i <= n; i ++)
high[i] = lower_bound(A + , A + a + , high[i]) - A;
Kruskal();
Dfs(impjs, );
Pre();
for(int i = ; i <= n; i ++) {
Root[i] = Root[i - ];
Insert(Root[i], , n, high[bef[i]]);
}
for(; Q; Q --) {
int v = read(), x = read(), k = read();
if(Ans != -) v ^= Ans, x ^= Ans, k ^= Ans;
int use = Imp_find(v, x);
Sec_A(Root[lst[use] - ], Root[rst[use]], , n, k);
if(Ans != -) Ans = A[Ans];
printf("%d\n", Ans);
}
return ;
}
bzoj 3551的更多相关文章
- 【BZOJ 3545】【ONTAK 2010】Peaks & 【BZOJ 3551】【ONTAK 2010】Peaks加强版 Kruskal重构树
sunshine的A题我竟然调了一周!!! 把循环dfs改成一个dfs就可以,,,我也不知道为什么这样就不会RE,但它却是A了,,, 这周我一直在调这个题,总结一下智障错误: 1.倍增的范围设成了n而 ...
- BZOJ 3551 Peaks加强版
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3551 题意:给出一个图,n个点,m条边.边有权值点也有权值.若干询问,(v,x,k),问从 ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- ●BZOJ 3551 [ONTAK2010]Peaks(在线)
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3551 题解: 最小生成树 Kruskal,主席树,在线 这个做法挺巧妙的...以Kruska ...
- BZOJ 3551/3545: [ONTAK2010]Peaks加强版 (Kruskal树+dfs序上的主席树+倍增)
Orz PoPoQQQ 学到了维护子树信息的时候用dfsdfsdfs序套主席树节省线段树空间. 学到了怎么用指针写可持久化线段树-emmm- CODE 只贴上3551加强版带强制在线的代码 #incl ...
- bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- bzoj 3551: [ONTAK2010]Peaks加强版
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- 【Peaks加强版 BZOJ 3551】你被坑了吗?
这道在没加读入优化时间在20s左右的题终于在大米饼两天的死缠烂打.鬼混.乱整乱撞后艰难地AC了.但惋惜的是,大米饼一号代码其实更加简洁,但至今找不出BUG,我将它放在下面,也许有一天从远方来的另一个大 ...
- bzoj 3551 kruskal重构树dfs序上的主席树
强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...
- BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...
随机推荐
- 去除element-ui table表格右侧滚动条的高度
/* //element-ui table的去除右侧滚动条的样式 */ ::-webkit-scrollbar { width: 1px; height: 1px; } /* // 滚动条的滑块 */ ...
- python03-break、continue、for循环、数据bytes类型、字符串与字节的关系、变量指向与深浅拷贝、set集合、文件操作
目录: 1.break.continue 2.for循环 3.数据bytes类型 4.字符串与字节的关系 5.变量指向与深浅拷贝 6.set集合 7.文件操作 一.break.continue bre ...
- Eclipse 反编译工具 jad
** 1 下载 jad工具 ** 2 将.exe文件放在jdk安装路径下,里面有java ,javac 等命令,然后将jad.jar放在eclipse的dropins目录下 ** 3 启动eclips ...
- 【vue】过滤器的使用
一.在methods中使用过滤器------全局定义的过滤器 //main.js中 import Vue from 'vue' Vue.filter('testFilter1',function(va ...
- mac OS下 安装MySQL 5.7
Mac OS X 下 TAR.GZ 方式安装 MySQL 5.7 与 MySQL 5.6 相比, 5.7 版本在安装时有两处不同: 1:初始化方式改变, 从scripts/mysql_install_ ...
- Linux学习笔记:split切分文件并按规律命名及添加拓展名
基础知识 功能:使用 shell 的 split 可以将一个大文件分割成很多个小文件,有时文件太大处理起来不方便就需要使用到了. 在默认情况下将按照每1000行切割成一个小文件. 语法: split ...
- flex 布局方式
开始啦 1. flex-direction 有关主轴的对齐方式 column 自上到下 row 自左到右 -->默认值 row-reverse 自右到左 column-reverse 自下到上 ...
- js获取地理位置
直接上代码: if(navigator.geolocation) { navigator.geolocation.getCurrentPosition( function (position) { v ...
- MacOS文本编辑无法打不开GB18030
不要直接双击打开 而是 打开sublime text或者其他文本编辑后,从软件里面的open选型打开
- 微信小程序开发(十三)安卓手机调用wx.getConnectedWifi API失败
安卓手机调用wx.getConnectedWifi API失败,返回的错误码是12000.需要先startWifi 接口: wx.startWifi({ success(res) { console. ...