zoukankan      html  css  js  c++  java
  • BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

     不难...treap + 启发式合并 + 并查集 搞搞就行了

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

     

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
     
    #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 = 100000 + 5;
     
    int p[maxn];
     
    struct node *null, *pt;
    struct node {
    node* ch[2];
    int v, s, r, x;
    node(int _v = 0, int _x = 0) : v(_v), x(_x), s(1), r(rand()) {
    ch[0] = ch[1] = null;
    }
    inline int cmp(int _v) {
    if(v == _v) return -1;
    return _v < v ? 0 : 1;
    }
    inline void maintain() {
    s = ch[0]->s + ch[1]->s + 1;
    }
    void* operator new (size_t) { return pt++; }
    };
     
    node* root[maxn], N[maxn * 30];
     
    void rotate(node* &o, int d) {
    node* k = o->ch[d ^ 1];
    o->ch[d ^ 1] = k->ch[d];
    k->ch[d] = o;
    o->maintain(); k->maintain();
    o = k;
    }
     
    int x, v;
    void insert(node* &o) {
    if(o == null) o = new node(v, x);
    else {
    int d = v < o->v ? 0 : 1;
    insert(o->ch[d]);
    if(o->ch[d]->r > o->r) rotate(o, d ^ 1);
    }
    o->maintain();
    }
     
    void merge(node* &o, node* &O) {
    if(o == null) return;
    rep(i, 2) merge(o->ch[i], O);
    x = o->x; v = o->v;
    insert(O);
    }
     
    int kth(node* o, int k) {
    int s = o->ch[0]->s;
    if(k == s + 1) return o->x;
    return k <= s ? kth(o->ch[0], k) : kth(o->ch[1], k - s - 1);
    }
     
    int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); }
     
    void init(int n) {
    pt = N;
    null = new(node);
    rep(i, n) root[p[i] = i] = null;
    null->s = 0;
    }
     
    void B(int u, int v) {
    int x = find(u), y = find(v);
    if(x != y) {
    if(root[x]->s > root[y]->s) swap(x, y);
    p[x] = y;
    merge(root[x], root[y]);
    }
    }
     
    int query(int x, int k) {
    int X = find(x);
    if(k > root[X]->s) return -1;
    return kth(root[X], k);
    }
     
    int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    init(n);
    rep(i, n) {
    x = i + 1;
    scanf("%d", &v);
    insert(root[i]);
    }
    while(m--) {
    int u, v;
    scanf("%d%d", &u, &v);
    B(u - 1, v - 1);
    }
    scanf("%d", &m);
    while(m--) {
    int u, v;
    char op;
    scanf(" %c%d%d", &op, &u, &v);
    if(op == 'B') B(u - 1, v - 1);
    else printf("%d ", query(u - 1, v));
    }
    return 0;
    }

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

    2733: [HNOI2012]永无乡

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1455  Solved: 771
    [Submit][Status][Discuss]

    Description

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。 
     

    Input

    输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 20%的数据 n≤1000,q≤1000 
     
    对于 100%的数据 n≤100000,m≤n,q≤300000 
     

    Output

    对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。 
     

    Sample Input

    5 1
    4 3 2 5 1
    1 2
    7
    Q 3 2
    Q 2 1
    B 2 3
    B 1 5
    Q 2 1
    Q 2 4
    Q 2 3

    Sample Output

    -1
    2
    5
    1
    2

    HINT

    Source

  • 相关阅读:
    C#几种截取字符串的方法小结
    KinSlideshow参数设置说明
    WinForm程序中两份mdf文件问题的解决
    全国省市数据库
    ASP.NET项目中使用CKEditor +CKFinder 实现上传图片
    mht文件无法打开的解决办法
    Non-parametric tests
    Plot transpant lines in Matleb 在Matlab中绘制透明线条
    Which HRV method to use: FFT or Autoregressive?
    SPM How-tos SPM预处理及统计分析指南
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4470122.html
Copyright © 2011-2022 走看看