[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加强版

[ONTAK2010]Peaks

[BZOJ3545][ONTAK2010]Peaks

P4197 Peaks&&P7834 [ONTAK2010] Peaks 加强版

P4197 Peaks&&P7834 [ONTAK2010] Peaks 加强版