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高的是多少. 强制在线. \ ...
随机推荐
- BOM与DOM的区别与联系
一.BOM与DOM的区别 1.BOM(Browser Object Model) BOM 即浏览器对象模型,BOM没有相关标准,BOM的最核心对象是window对象.window对象既为javascr ...
- (八)Struts标签基础(一)
一.Struts标签分类 二.标签的使用 2.1 标签的主题 主题的设置与struts.xml中的常量<constant name="struts.ui.theme" val ...
- C++万能头文件<bits/stdc++.h>的内容与优缺点
最近发现了一个C++的头文件bits/stdc++.h,听说这是一个几乎包含了所有C++库函数的头文件,就想更深入的了解一下,下面是头文件内容 // C++ includes used for pre ...
- 洛谷 P1540 机器翻译
链接:https://www.luogu.org/problemnew/show/p1540 题目: 题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译 ...
- java 传入用户名和密码并自动提交表单实现登录到其他系统
不用单点登录,模拟远程项目的登录页面表单,在访问这个页面的时候自动提交表单到此项目的登录action,就可以实现登录到其他系统. ssh框架项目 1.以下是本地系统的action代码: import ...
- node express4 + 前端自动刷新
官网快速生成:http://www.expressjs.com.cn/starter/generator.html 1.安装 express 1.应用生成器工具 express-generator ...
- form-create教程:给内置组件和自定义组件添加事件
本文将介绍form-create如何给内置组件和自定义组件添加事件 form-create 是一个可以通过 JSON 生成具有动态渲染.数据收集.验证和提交功能的表单生成器.并且支持生成任何 Vue ...
- JS 断点调试心得
1.断点调试是啥?难不难? 断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了.操作起来似乎很简单,其实很多人纠结的是,是在哪里打断 ...
- 2 vue学习
1 vue的核心是数据与视图的双向绑定 2 当viewmodel销毁时,所有的事件处理器都会自动删除,无需自己清理 3 v-model的修饰符解释 .lazy :失去焦点或者按回车键时触发同步 .nu ...
- Java 面向对象(七)多态
一.多态概述(Polymorphism) 1.引入 多态是继封装.继承之后,面向对象的第三大特性. 通过不同的事物,体现出来的不同的形态.多态,描述的就是这样的状态.如跑的动作,每个动物的跑的动作就是 ...