版权声明:欢迎大家转载,转载请注明出处 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;
}