UVALive 5031 Graph and Queries——Treap+并查集

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82458512

1A

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int maxm = 6e5 + 10;
struct Node {
    Node *ch[2];
    int r, v, s;
    Node (int v):v(v) { ch[0] = ch[1] = NULL; r = rand(); s = 1; }
    bool operator < (const Node &rhs) const {
        return r < rhs.r;
    }
    int cmp(int x) const {
        if (x == v) return -1;
        return x < v ? 0 : 1;
    }
    void maintain() {
        s = 1;
        if (ch[0] != NULL) s += ch[0]->s;
        if (ch[1] != NULL) s += ch[1]->s;
    }
};

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;
}

void insert(Node *&o, int x) {
    if (o == NULL) o = new Node(x);
    else {
        int d = (x < o->v ? 0 : 1);
        insert(o->ch[d], x);
        if (o->ch[d]->r > o->r) rotate(o, d^1);
    }
    o->maintain();
}

void remove(Node *&o, int x) {
    int d = o->cmp(x);
    if (d == -1) {
        Node *u = o;
        if (o->ch[0] != NULL && o->ch[1] != NULL) {
            int d2 = (o->ch[0]->r > o->ch[1]->r ? 1 : 0);
            rotate(o, d2); remove(o->ch[d2], x);
        }
        else {
            if (o->ch[0] == NULL) o = o->ch[1]; else o = o->ch[0];
            delete u;
        }
    }
    else remove(o->ch[d], x);
    if (o != NULL) o->maintain();
}

int kth(Node *o, int k) {
    if (o == NULL || k <= 0 || k > o->s) return 0;
    int s = (o->ch[1] == NULL ? 0 : o->ch[1]->s);
    if (k == s + 1) return o->v;
    else if (k <= s) return kth(o->ch[1], k);
    else return kth(o->ch[0], k-s-1);
}

Node *root[maxn];
void merge(Node *&a, Node *&b) {
    if (a->ch[0] != NULL) merge(a->ch[0], b);
    if (a->ch[1] != NULL) merge(a->ch[1], b);
    insert(b, a->v);
    delete a;
    a = NULL;
}

int ks, n, m, val[maxn];
char op[maxm];
int x[maxm], y[maxm];
struct E { int u, v; } e[maxm];
bool vis[maxn];

int fa[maxn];
void init_bcj() {
    for (int i = 0; i <= n; i++) fa[i] = i;
}
int query(int x) {
    return (x == fa[x] ? x : fa[x] = query(fa[x]));
}
int mem, head[maxn];
struct Edge { int to, next, id; } edges[maxm<<1];
void init_edges() {
    mem = 0;
    for (int i = 0; i <= n; i++) head[i] = -1;
}
void addedge(int u, int v, int id) {
    edges[mem].to = v, edges[mem].id = id; edges[mem].next = head[u]; head[u] = mem++;
}

void dfs(int u, int f) {
    fa[u] = f;
    vis[u] = 1;
    for (int i = head[u]; ~i; i = edges[i].next) {
        int v = edges[i].to;
        if (vis[v]) continue;
        insert(root[f], val[v]);
        dfs(v, f);
    }
}

void init() {
    init_edges();
    init_bcj();
}

int main() {
    while (~scanf("%d%d", &n, &m) && n + m) {
        init();
        for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
        for (int i = 1; i <= m; i++) scanf("%d%d", &e[i].u, &e[i].v);
        char c[10];
        int cnt = 0;
        for (int i = 0; i <= m; i++) vis[i] = 0;
        while (~scanf("%s", c) && c[0] != 'E') {
            ++cnt;
            if (c[0] == 'D') {
                op[cnt] = c[0];
                scanf("%d", &x[cnt]);
                vis[x[cnt]] = 1;
            }
            else if (c[0] == 'Q') {
                op[cnt] = c[0];
                scanf("%d%d", &x[cnt], &y[cnt]);
            }
            else {
                op[cnt] = c[0];
                scanf("%d%d", &x[cnt], &y[cnt]);
                swap(val[x[cnt]], y[cnt]);
            }
        }
        for (int i = 1; i <= m; i++) {
            if (!vis[i]) {
                addedge(e[i].u, e[i].v, i);
                addedge(e[i].v, e[i].u, i);
            }
        }
        for (int i = 1; i <= n; i++) root[i] = NULL, vis[i] = 0;
        for (int i = 1; i <= n; i++) {
            if (vis[i]) continue;
            insert(root[i], val[i]);
            dfs(i, i);
        }

        int res = 0;
        double ans = 0;
        for (int i = cnt; i >= 1; i--) {
            if (op[i] == 'D') {
                int idx = x[i];
                int u = e[idx].u, v = e[idx].v;
                u = query(u), v = query(v);
                if (u == v) continue;
                if (root[u]->s > root[v]->s) {
                    fa[v] = u;
                    merge(root[v], root[u]);
                }
                else {
                    fa[u] = v;
                    merge(root[u], root[v]);
                }
            }
            else if (op[i] == 'Q') {
                int f = query(x[i]);
                int t = kth(root[f], y[i]);
                res++;
                ans += t;
            }
            else {
                int f = query(x[i]);
                remove(root[f], val[x[i]]);
                insert(root[f], y[i]);
                val[x[i]] = y[i];
            }
        }
        if (res) ans /= res;
        printf("Case %d: %.6lf\n", ++ks, ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/82458512