按照困难度升序排序
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的更多相关文章

  1. 【BZOJ 3545】【ONTAK 2010】Peaks & 【BZOJ 3551】【ONTAK 2010】Peaks加强版 Kruskal重构树

    sunshine的A题我竟然调了一周!!! 把循环dfs改成一个dfs就可以,,,我也不知道为什么这样就不会RE,但它却是A了,,, 这周我一直在调这个题,总结一下智障错误: 1.倍增的范围设成了n而 ...

  2. BZOJ 3551 Peaks加强版

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3551 题意:给出一个图,n个点,m条边.边有权值点也有权值.若干询问,(v,x,k),问从 ...

  3. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  4. ●BZOJ 3551 [ONTAK2010]Peaks(在线)

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3551 题解: 最小生成树 Kruskal,主席树,在线 这个做法挺巧妙的...以Kruska ...

  5. BZOJ 3551/3545: [ONTAK2010]Peaks加强版 (Kruskal树+dfs序上的主席树+倍增)

    Orz PoPoQQQ 学到了维护子树信息的时候用dfsdfsdfs序套主席树节省线段树空间. 学到了怎么用指针写可持久化线段树-emmm- CODE 只贴上3551加强版带强制在线的代码 #incl ...

  6. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  7. bzoj 3551: [ONTAK2010]Peaks加强版

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  8. 【Peaks加强版 BZOJ 3551】你被坑了吗?

    这道在没加读入优化时间在20s左右的题终于在大米饼两天的死缠烂打.鬼混.乱整乱撞后艰难地AC了.但惋惜的是,大米饼一号代码其实更加简洁,但至今找不出BUG,我将它放在下面,也许有一天从远方来的另一个大 ...

  9. bzoj 3551 kruskal重构树dfs序上的主席树

    强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...

  10. BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...

随机推荐

  1. jq勾选

    1.取消勾选 $("box").attr("checked", false); 2.勾选 $("kbox").attr("chec ...

  2. 2019牛客多校三 A. Graph Games (图分块)

    大意: 给定无向图, 定义$S(x)$为$x$的邻接点集合. 每次操作翻转$[L,R]$范围的边, 询问$S(x)$与$S(y)$是否相等. 快速判断集合相等可以用$CF 799F$的技巧. 采用$h ...

  3. (二十二)SpringBoot之使用Druid连接池以及SQL监控和spring监控

    一.引入maven依赖 <dependencies> <dependency> <groupId>org.springframework.boot</grou ...

  4. KNN算法识别手写数字

    需求: 利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别: 先验数据(训练数据)集: ♦数据维度比较大,样本数比较多. ♦ 数据集包括数字0-9的手写体. ♦每个数字大约有20 ...

  5. Django rest-framework框架-组件之路由

    路由: a. url(r'^(?P<version>[v1|v2]+)/v1/$',views.ViewView.as_view()) url(r'^(?P<version>[ ...

  6. Go part 3 指针,栈与堆

    指针类型 要明白指针,需要知道几个概念:指针地址,指针类型 和 指针取值 取指针地址 每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置,使用 & 放在变量前面进行“取指针地址”操 ...

  7. Docker多阶段构建实战(multi-stage builds)

    在编写Dockerfile构建docker镜像时,常遇到以下问题: RUN命令会让镜像新增layer,导致镜像变大,虽然通过&&连接多个命令能缓解此问题,但如果命令之间用到docker ...

  8. Unity UGUI Button 无法点击问题一例

    理论上,只要一个按钮自己这一层或者子节点有一个控件勾选了RaycastTarget,并且按钮为Interactable的.并且不被其他可以点击的控件阻挡,那么这个按钮就可以被点击 在调一个界面时发现一 ...

  9. window下redis的安装和使用

    1.下载及安装redis 下载地址:https://github.com/dmajkic/redis/downloads 找到对应的版本下载安装 打开cmd窗口,用cd命令进入到安装redis的根目录 ...

  10. Sliverlight/WPF 样式使用方法

    1,UserControl 页面级样式: UserControl.Resources style setter Property value. TargetType为应用的类型 <UserCon ...