Eterna_King

导航

[HNOI2012]永无乡

日了狗了,原来启发式合并是个暴力,我真是见鬼了,直接把size小的平衡树暴力插进去,我以为是啥高级算法。

//author Eterna
#define Hello the_cruel_world!
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<utility>
#include<cmath>
#include<climits>
#include<deque>
#include<functional>
#include<complex>
#include<numeric>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define Pi acos(-1.0)
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#define pb(x) push_back(x)
#define lowbit(x) (x & -x)
#define FRIN freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\in.txt", "r", stdin)
#define FROUT freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\out.txt", "w", stdout)
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ls(x) arr[x].child[0]
#define rs(x) arr[x].child[1]
#define out(x) printf("%d\n", x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int maxn = 1e5;
const int INF = 0x7fffffff;
const int mod = 19260817;
const double eps = 1e-7;
inline int read_int() {
    char c;
    int ret = 0, sgn = 1;
    do { c = getchar(); } while ((c < '0' || c > '9') && c != '-');
    if (c == '-') sgn = -1; else ret = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    return sgn * ret;
}
inline ll read_ll() {
    char c;
    ll ret = 0, sgn = 1;
    do { c = getchar(); } while ((c < '0' || c > '9') && c != '-');
    if (c == '-') sgn = -1; else ret = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    return sgn * ret;
}
struct node{
    int child[2], value, key, size;
}arr[20 * maxn + 5];
int tot;
inline void Push_Up(int index){
    arr[index].size = arr[ls(index)].size + arr[rs(index)].size + 1;
}
void Split(int root, int& x, int& y, int value){
    if(!root){
        x = y = 0;
        return;
    }
    if(arr[root].value <= value)x = root, Split(rs(root), rs(x), y, value);
    else y = root, Split(ls(root), x, ls(y), value);
    Push_Up(root);
}
void Merge(int& root, int x, int y){
    if(!x || !y){
        root = x + y;
        return;
    }
    if(arr[x].key < arr[y].key)root = x, Merge(rs(root), rs(x), y);
    else root = y, Merge(ls(root), x, ls(y));
    Push_Up(root);
}
inline void Insert(int& root, int value){
    int x = 0, y = 0, z = ++tot;
    arr[z].value = value, arr[z].size = 1, arr[z].key = rand();
    Split(root, x, y, value);
    Merge(x, x, z);
    Merge(root, x, y);
}
inline int kth_number(int root, int k){
    while(arr[ls(root)].size + 1 != k){
        if(arr[ls(root)].size >= k)root = ls(root);
        else k -= (arr[ls(root)].size + 1), root = rs(root);
    }
    return arr[root].value;
}
void DFS(int now, int& root){
    if(now)Insert(root, arr[now].value);
    if(ls(now))DFS(ls(now), root);
    if(rs(now))DFS(rs(now), root);
}
int ufs[maxn + 5], root[maxn + 5], Rank[maxn + 5];
inline int find(int x){
    return x == ufs[x] ? x : ufs[x] = find(ufs[x]);
}
void unite(int x, int y){
    x = find(x), y = find(y);
    if(x != y){
        if(arr[root[x]].size > arr[root[y]].size)swap(x, y);
        DFS(root[x], root[y]);
        ufs[x] = y;
    }
}
int n, m, q;
char op;
int main()
{
    n = read_int(), m = read_int();
    for(int i = 1; i <= n; ++i){
        ufs[i] = i;
        int x = read_int();
        Rank[x] = i;
        Insert(root[i], x);
    }
    while(m--){
        int x = read_int(), y = read_int();
        unite(x, y);
    }
    q = read_int();
    while(q--){
        scanf(" %c", &op);
        if(op == 'Q'){
            int x = read_int(), k = read_int();
            x = find(x);
            if(arr[root[x]].size < k)out(-1);
            else {
                int m = kth_number(root[x], k);
                out(Rank[m]);
            }
        } else {
            int x = read_int(), y = read_int();
            unite(x, y);
        }
    }
    return 0;
}

 

posted on 2019-03-19 20:47  Eterna_King  阅读(122)  评论(0编辑  收藏  举报