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高的是多少. 强制在线. \ ...
随机推荐
- 位、字,字节与KB的关系?
位:我们常说的bit,位就是传说中提到的计算机中的最小数据单位:说白了就是0或者1:计算机内存中的存储都是01这两个东西. 字节:英文单词:(byte),byte是存储空间的基本计量单位.1byte ...
- Layui连接mysql操作CRUD案例
今天分享的是一个新前端框架Layui,用它来链接数据库实现一下crud的操作. 一:layui简历 layui,是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与 ...
- CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败
今天在使用 C# 操作 Excel 时,一直在报错误: 检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败,原因是出现以下 ...
- powerdesign中逆向工程后name和comment的互换
powerdesign 中,将数据库中可以逆向生成pdm的结构图,比较清晰看到系统的结构, 但假如是db先行的话,一般是db中的每个列中用comment中文注释说明这列是 干什么的,但逆向工程后,会发 ...
- 经典SQL数据库面试题以及答案—Oracle版本-SQL全部在plsql开发编写-欢迎提问
Student(Sno,Sname,Sage,Ssex) 学生表 S1:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别 Course(Cno,Cname,T1) 课程表 C1,课程 ...
- HTTP参数污染(参数处理图)
- 3d转化
3d转化 想要实现3d效果,首先要确定的是观察点,这是2d转换所不需要的.具体的我也看的很糊涂,美术什么的根本不懂好吗. 但有些东西是确定的,perspective定义的是3d元素距视图的距离,因此像 ...
- dockerfile构建nginx
mkdir docker_demo cd docker_demo wget http://nginx.org/download/nginx-1.2.9.tar.gz vim Dockerfile FR ...
- hive 存储格式对比
Apache Hive支持Apache Hadoop中使用的几种熟悉的文件格式,如TextFile,RCFile,SequenceFile,AVRO,ORC和Parquet格式. Cloudera I ...
- linux cenos开放端口
问题:8080端口不能访问 解决方案: 第1步 查看阿里云端口是否开放 网络安全>安全组>配置规则>添加入方向 第二步 查看防火墙是否开启(只说开启了防火墙的情况) 查看防火墙状态: ...