[ONTAK2010] Peaks
Posted evenbao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ONTAK2010] Peaks相关的知识,希望对你有一定的参考价值。
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=3545
[算法]
离线加边 , 用并查集维护连通性 , 然后线段树合并即可
时间复杂度 : O(NlogN)
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; const int MAXM = 5e5 + 10; const int MAXQ = 5e5 + 10; const int MAXP = 3e6 + 10; typedef long long ll; typedef long double ld; typedef unsigned long long ull; struct edge { int u , v , w; } e[MAXM]; struct query { int u , x , k; int id; } que[MAXQ]; int n , m , q , len; int fa[MAXN] , ans[MAXQ] , h[MAXN] , val[MAXN] , rt[MAXN]; struct Segment_Tree { int sz; struct Node { int lc , rc; int cnt; } a[MAXP]; Segment_Tree() { sz = 0; } inline int merge(int x , int y) { if (x == 0 || y == 0) return x + y; a[x].cnt += a[y].cnt; a[x].lc = merge(a[x].lc , a[y].lc); a[x].rc = merge(a[x].rc , a[y].rc); return x; } inline void update(int x) { a[x].cnt = a[a[x].lc].cnt + a[a[x].rc].cnt; } inline void modify(int &now , int l , int r , int x , int value) { if (!now) now = ++sz; if (l == r) { a[now].cnt += value; return; } int mid = (l + r) >> 1; if (mid >= x) modify(a[now].lc , l , mid , x , value); else modify(a[now].rc , mid + 1 , r , x , value); update(now); } inline int query(int now , int l , int r , int k) { if (l == r) return l; int mid = (l + r) >> 1; if (a[a[now].rc].cnt >= k) return query(a[now].rc , mid + 1 , r , k); else return query(a[now].lc , l , mid , k - a[a[now].rc].cnt); } inline int query(int x , int k) { if (a[rt[x]].cnt < k) return -1; else return query(rt[x] , 1 , len , k); } } SGT; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘; x *= f; } inline bool cmpa(edge a , edge b) { return a.w < b.w; } inline bool cmpb(query a , query b) { return a.x < b.x; } inline int get_root(int x) { if (fa[x] == x) return x; else return fa[x] = get_root(fa[x]); } int main() { read(n); read(m); read(q); for (int i = 1; i <= n; i++) { read(h[i]); val[i] = h[i]; } for (int i = 1; i <= n; i++) fa[i] = i; sort(val + 1 , val + n + 1); len = unique(val + 1 , val + n + 1) - val - 1; for (int i = 1; i <= n; i++) h[i] = lower_bound(val + 1 , val + len + 1 , h[i]) - val; for (int i = 1; i <= n; i++) SGT.modify(rt[i] , 1 , len , h[i] , 1); for (int i = 1; i <= m; i++) { read(e[i].u); read(e[i].v); read(e[i].w); } for (int i = 1; i <= q; i++) { read(que[i].u); read(que[i].x); read(que[i].k); que[i].id = i; } sort(e + 1 , e + m + 1 , cmpa); sort(que + 1 , que + q + 1 , cmpb); int now = 1; for (int i = 1; i <= q; i++) { while (now <= m && e[now].w <= que[i].x) { if (get_root(e[now].u) != get_root(e[now].v)) { rt[get_root(e[now].v)] = SGT.merge(rt[get_root(e[now].u)] , rt[get_root(e[now].v)]); fa[get_root(e[now].u)] = get_root(e[now].v); } ++now; } int tmp = SGT.query(get_root(que[i].u) , que[i].k); if (tmp == -1) ans[que[i].id] = -1; else ans[que[i].id] = val[tmp]; } for (int i = 1; i <= q; i++) printf("%d " , ans[i]); return 0; }
以上是关于[ONTAK2010] Peaks的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树
bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版