1. 程式人生 > >[ONTAK2010] Peaks

[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\n" , ans[i]); return 0; }