zoukankan      html  css  js  c++  java
  • [luogu4197]Peaks

    Problem

    传送门

    给你一张n个点,m条边的图,边有边权,点有点权。

    现有Q个询问,每次询问从点x开始,只走边权小于y的边,能走到的点中点权第k大的点

    Solution

    这道题没有强制在线,所以直接想了一个简单的离线做法。

    将询问按照y排序,边按照边权排序。

    将边按顺序一条一条加入,合并了两个联通块的同时合并权值线段树

    至于查询,在权值线段树查询全局的k大就可以了。

    不知道为什么大家都打的启发式合并+主席树

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
    #define mp make_pair
    #define fst first
    #define snd second
    
    template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
    template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
    
    inline int read(){
        int res = 0, fl = 1;
        char r = getchar();
        for (; !isdigit(r); r = getchar()) if(r == '-') fl = -1;
        for (; isdigit(r); r = getchar()) res = (res << 3) + (res << 1) + r - 48;
        return res * fl;
    }
    typedef long long LL;
    typedef pair<int, int> pii;
    const int Maxn = 5e5 + 10;
    namespace SGT{
        int tre[Maxn << 4], ls[Maxn << 4], rs[Maxn << 4], cnt;
    #define mid ((l + r) >> 1)
    #define sum tre[rs[rt]]
        inline void Insert(int &rt, int l, int r, int pos){
            if(!rt) rt = ++cnt;
            tre[rt]++;
            if(l == r) return;
            if(mid >= pos) Insert(ls[rt], l, mid, pos);
            else Insert(rs[rt], mid + 1, r, pos);
        }
        inline int Query(int rt ,int l, int r, int k){
            if(tre[rt] < 0) return -1;
            if(tre[rt] < k) return -1;
            if(l == r) return l;
            if(sum >= k) return Query(rs[rt], mid + 1, r, k);
            else return Query(ls[rt], l, mid, k - sum);
        }
        inline int merge(int u, int v){
            if(!u) return v;
            if(!v) return u;
            tre[u] += tre[v];
            ls[u] = merge(ls[u], ls[v]);
            rs[u] = merge(rs[u], rs[v]);
            return u;
        }
    #undef mid 
    #undef sum
    }
    struct node {
        int x, y, val, id;
        bool operator < (const node T) const{ return val < T.val;}
    }g[Maxn],ASK[Maxn];
    int ans[Maxn], fa[Maxn], h[Maxn], b[Maxn], root[Maxn], num;
    bool vis[Maxn];
    vector <int> G[Maxn];
    inline int get_fa(int x){ return fa[x] == x ? x : fa[x] = get_fa(fa[x]);}
    inline void link(int u, int v){
        if(get_fa(u) == get_fa(v)) return;
        root[get_fa(v)] = SGT::merge(root[get_fa(u)], root[get_fa(v)]);
        fa[get_fa(u)] = get_fa(v);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in", "r", stdin);
        freopen("a.out", "w", stdout);
    #endif
        int n = read(), m = read(), Q = read();
        for (int i = 1; i <= n; ++i) b[i] = h[i] = read();
        sort(b + 1, b + 1 + n);
        num = unique(b + 1, b + 1 + n) - b - 1;
        for (int i = 1; i <= n; ++i) h[i] = lower_bound(b + 1, b + 1 + num, h[i]) - b;
        for (int i = 1; i <= m; ++i)
            g[i].x = read(), g[i].y = read(), g[i].val = read();
        sort(g + 1, g + 1 + m);
        for (int i = 1; i <= Q; ++i)
            ASK[i].x = read(), ASK[i].val = read(), ASK[i].y = read(),ASK[i].id = i;
        sort(ASK + 1, ASK + 1 + Q);
        for (int i = 1; i <= n; ++i) fa[i] = i;
        for (int i = 1; i <= n; ++i)
            SGT::Insert(root[i], 1, num, h[i]);
        int top = 1;
        for (int i = 1; i <= m; ++i){
            for(; ASK[top].val < g[i].val && top <= Q; ++top){
                ans[ASK[top].id] = SGT::Query(root[get_fa(ASK[top].x)], 1, num, ASK[top].y);
                vis[ASK[top].id] = 1;
            }
            link(g[i].x, g[i].y);
        }
        for (int i = top; i <= Q; ++i)
            ans[ASK[i].id] = SGT::Query(root[get_fa(ASK[i].x)], 1, num, ASK[i].y);
        b[0] = -1;
        for (int i = 1; i <= Q; ++i)
            printf("%d
    ",b[max(ans[i], 0)]);
        return 0;
    }
    
  • 相关阅读:
    spring多个数据源配置
    BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
    Codeforces Round #321 (Div. 2) E. Kefa and Watch 线段树hash
    Codeforces Round #321 (Div. 2) D. Kefa and Dishes 状压dp
    Codeforces Round #321 (Div. 2) C. Kefa and Park dfs
    Codeforces Round #321 (Div. 2) B. Kefa and Company 二分
    Codeforces Round #321 (Div. 2) A. Kefa and First Steps 水题
    Codeforces Round #268 (Div. 1) B. Two Sets 暴力
    Codeforces Round #268 (Div. 1) A. 24 Game 构造
    2015北京网络赛 F Couple Trees 暴力倍增
  • 原文地址:https://www.cnblogs.com/LZYcaiji/p/10611169.html
Copyright © 2011-2022 走看看