zoukankan      html  css  js  c++  java
  • [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;
        
    }
  • 相关阅读:
    C#调试信息打印到输出窗口
    C#拼接SQL中in条件
    从图像到知识:深度神经网络实现图像理解的原理解析
    Cocoa Touch(六):App运行机制 NSRunLoop, KVC, KVO, Notification, ARC
    Cocoa Touch(五):网络请求 NSURLSession/AFNetworking, GCD, NSURLResquest
    JQuery:选择器、动画、AJAX请求
    Cocoa Touch(四): 多线程GCD, NSObject, NSThread, NSOperationQueue
    Socket、RPC通信实例,简单版本,仅供查阅
    Cocoa Touch(三):图形界面UIKit、Core Animation、Core Graphics
    Cocoa Touch(二):数据存储CoreData, NSKeyArchiver, NSOutputStream, NSUserDefaults
  • 原文地址:https://www.cnblogs.com/evenbao/p/10203399.html
Copyright © 2011-2022 走看看