zoukankan      html  css  js  c++  java
  • BZOJ 3545: [ONTAK2010]Peaks( BST + 启发式合并 + 并查集 )

    这道题很好想, 离线, 按询问的x排序从小到大, 然后用并查集维护连通性, 用平衡树维护连通块的山的权值, 合并就用启发式合并.时间复杂度的话, 排序是O(mlogm + qlogq), 启发式合并是O(nlog²n), 询问是O(qlogn).

    -------------------------------------------------------------------

    #include<bits/stdc++.h>
     
    #define rep(i, n) for(int i = 0; i < n; ++i)
    #define clr(x, c) memset(x, c, sizeof(x))
     
    using namespace std;
     
    const int maxn = 100009;
    const int maxq = 500009;
     
    struct Node {
    Node* ch[2];
    int s, r, v;
    Node():r(rand()) {}
    inline void upd() {
    s = ch[0]->s + ch[1]->s + 1;
    }
    } pool[maxn * 20], *pt = pool, *root[maxn], *null;
     
    Node* newNode(int v) {
    pt->ch[0] = pt->ch[1] = null;
    pt->s = 1, pt->v = v;
    return pt++;
    }
     
    void init() {
    null = pt++;
    null->s = 0;
    null->ch[0] = null->ch[1] = null;
    }
     
    void rotate(Node* &t, int d) {
    Node* h = t->ch[d ^ 1];
    t->ch[d ^ 1] = h->ch[d];
    h->ch[d] = t;
    t->upd(), h->upd();
    t = h;
    }
     
    void insert(Node* &t, int v) {
    if(t == null) 
       t = newNode(v);
    else {
    int d = v <= t->v;
    insert(t->ch[d], v);
    if(t->ch[d]->r > t->r) rotate(t, d ^ 1);
    }
    t->upd();
    }
     
    void del(Node* &t, int v) {
    int d = v == t->v ? -1 : v < t->v;
    if(d == -1) {
    if(t->ch[0] != null && t->ch[1] != null) {
    int h = t->ch[0]->r > t->ch[1]->r;
    rotate(t, h), del(t->ch[h], v);
    } else
       t = t->ch[0] == null ? t->ch[1] : t->ch[0];
    } else
       del(t->ch[d], v);
    if(t != null) t->upd();
    }
     
    int select(Node*t, int k) {
    if(k > t->s) return -1;
    for(; ;) {
    int s = t->ch[0]->s;
    if(k == s + 1) return t->v;
    if(k > s)
       k -= s + 1, t = t->ch[1];
    else
       t = t->ch[0];
    }
    }
     
    inline int read() {
    char c = getchar();
    for(; !isdigit(c); c = getchar());
    int ans = 0;
    for(; isdigit(c); c = getchar())
       ans = ans * 10 + c - '0';
    return ans;
    }
     
    int p[maxn];
     
    int find(int x) {
    return x == p[x] ? x : p[x] = find(p[x]);
    }
     
    inline void unite(int x, int y) {
    int a = find(x), b = find(y);
    p[a] = b;
    if(root[a] != root[b]) {
    if(root[a]->s > root[b]->s) swap(a, b);
    while(root[a] != null) {
    insert(root[b], root[a]->v);
    del(root[a], root[a]->v);
    }
    root[a] = root[b];
    }
    }
     
    struct Q {
    int x, lim, k, pos;
    inline void Read(int p) {
    x = read() - 1, lim = read(), k = read(), pos = p;
    }
    bool operator < (const Q &t) const {
    return lim < t.lim;
    }
    } A[maxq];
     
    struct edge {
    int u, v, w;
    inline void Read() {
    u = read() - 1, v = read() - 1, w = read();
    }
    bool operator < (const edge &e) const {
    return w < e.w;
    }
    } E[maxq];
     
    int ans[maxq];
     
    int main() {
    freopen("test.in", "r", stdin);
    init();
    int n, m, q, _p = 0;
    cin >> n >> m >> q;
    rep(i, n) root[i] = newNode(read());
    rep(i, n) p[i] = i;
    rep(i, m) E[i].Read(); sort(E, E + m);
    rep(i, q) A[i].Read(i); sort(A, A + q);
    rep(i, q) {
    Q* h = A + i;
    for(; E[_p].w <= h->lim && _p < m; _p++) unite(E[_p].u, E[_p].v);
    ans[h->pos] = select(root[find(h->x)], h->k);
    }
    rep(i, q) printf("%d ", ans[i]);
    return 0;
    }

    ------------------------------------------------------------------- 

    3545: [ONTAK2010]Peaks

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 816  Solved: 231
    [Submit][Status][Discuss]

    Description

    在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

    Input

    第一行三个数N,M,Q。
    第二行N个数,第i个数为h_i
    接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
    接下来Q行,每行三个数v x k,表示一组询问。

    Output

    对于每组询问,输出一个整数表示答案。

    Sample Input

    10 11 4
    1 2 3 4 5 6 7 8 9 10
    1 4 4
    2 5 3
    9 8 2
    7 8 10
    7 1 4
    6 7 1
    6 4 8
    2 1 5
    10 8 10
    3 4 7
    3 4 6
    1 5 2
    1 5 6
    1 5 8
    8 9 2

    Sample Output

    6
    1
    -1
    8


    HINT

    【数据范围】

    N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。

    Source

  • 相关阅读:
    python 取整的两种方法
    django class-based view 考古
    django缓存基于类的视图
    MySQL参数优化案例
    django后台使用MySQL情况下的事务控制详解
    讲讲python“=”运算符上的优雅语法
    p标签不折行的问题
    django-TDD
    session 和 flask_session 实现原理(源码解析)
    网关地址和网关IP是什么,他们有什么关系?
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4672082.html
Copyright © 2011-2022 走看看