1 #include<cstdio>
  2 #include<iostream>
  3 #define MAXN 400010
  4 #define PushUp(x) num[x] = num[next[x][0]] + num[next[x][1]] + 1;
  5 using namespace std;
  6 pair<int, int> edge[MAXN];
  7 int first[MAXN], next[MAXN], cost[MAXN], e;
  8 int father[MAXN];
  9 bool del[MAXN];
 10 struct ASK {
 11     char cmd;
 12     int x, k;
 13 } a[MAXN];
 14 struct SplayTree {
 15     int root;
 16     int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN];
 17     void Init() {
 18         root = next[0][0] = next[0][1] = pre[0] = num[0] = key[0] = 0;
 19     }
 20     inline void NewNode(int &x, int loc, int father, int val) {
 21         x = loc;
 22         next[x][0] = next[x][1] = 0;
 23         pre[x] = father;
 24         key[x] = val;
 25         num[x] = 1;
 26     }
 27     inline void Rotate(int x, int kind) {
 28         int y, z;
 29         y = pre[x];
 30         z = pre[y];
 31         next[y][!kind] = next[x][kind];
 32         pre[next[x][kind]] = y;
 33         next[z][next[z][1] == y] = x;
 34         pre[x] = z;
 35         next[x][kind] = y;
 36         pre[y] = x;
 37         PushUp(y);
 38     }
 39     void Splay(int x, int goal) {
 40         if (x != goal) {
 41             while (pre[x] != goal) {
 42                 if (next[pre[x]][0] == x)
 43                     Rotate(x, 1);
 44                 else
 45                     Rotate(x, 0);
 46             }
 47             PushUp(x);
 48             if (!goal)
 49                 root = x;
 50         }
 51     }
 52     int Select(int x, int k) {
 53         k = num[x] - k + 1;
 54         while (num[next[x][0]] + 1 != k) {
 55             if (num[next[x][0]] + 1 > k)
 56                 x = next[x][0];
 57             else {
 58                 k -= num[next[x][0]] + 1;
 59                 x = next[x][1];
 60             }
 61         }
 62         Splay(x, 0);
 63         return x;
 64     }
 65     void Insert(int x, int y, int val) {
 66         while (next[y][val > key[y]])
 67             y = next[y][val > key[y]];
 68         NewNode(next[y][val > key[y]], x, y, val);
 69     }
 70     void DFS(int x) {
 71         if (x) {
 72             DFS(next[x][0]);
 73             DFS(next[x][1]);
 74             Insert(x, root, key[x]);
 75             Splay(x, 0);
 76         }
 77     }
 78     void Join(int x, int y) {
 79         Splay(x, 0);
 80         Splay(y, 0);
 81         if (num[x] > num[y])
 82             swap(x, y);
 83         root = y;
 84         DFS(x);
 85     }
 86     int Query(int x, int k) {
 87         if (k < 1)
 88             return 0;
 89         Splay(x, 0);
 90         if (num[x] < k)
 91             return 0;
 92         return key[Select(x, k)];
 93     }
 94     void Change(int x, int val) {
 95         int a, b;
 96         Splay(x, 0);
 97         a = next[x][0];
 98         b = next[x][1];
 99         pre[a] = pre[b] = 0;
100         if (a && b) {
101             while (next[b][0])
102                 b = next[b][0];
103             next[b][0] = a;
104             pre[a] = b;
105             Splay(a, 0);
106             Insert(x, a, val);
107         } else if (a)
108             Insert(x, a, val);
109         else if (b)
110             Insert(x, b, val);
111         else
112             key[x] = val;
113         Splay(x, 0);
114     }
115 } spt;
116 int INT() {
117     bool neg;
118     int res;
119     char ch;
120     while (ch = getchar(), !isdigit(ch) && ch != '-')
121         ;
122     if (ch == '-') {
123         neg = true;
124         res = 0;
125     } else {
126         neg = false;
127         res = ch - '0';
128     }
129     for (; ch = getchar(), isdigit(ch);)
130         res = res * 10 + ch - '0';
131     return neg ? -res : res;
132 }
133 char CHAR() {
134     char ch;
135     while (ch = getchar(), !isalpha(ch))
136         ;
137     return ch;
138 }
139 int FindSet(int x) {
140     if (x != father[x])
141         father[x] = FindSet(father[x]);
142     return father[x];
143 }
144 inline void AddEdge(int x, int val) {
145     cost[e] = val;
146     next[e] = first[x];
147     first[x] = e++;
148 }
149 int main() {
150     int ca = 1;
151     double ans;
152     int n, m, q, i, cnt;
153     int x, y;
154     while (true) {
155         n = INT(), m = INT();
156         if (!n && !m)
157             break;
158         spt.Init();
159         for (e = 0, i = 1; i <= n; i++) {
160             father[i] = i;
161             first[i] = -1;
162             AddEdge(i, INT());
163         }
164         for (i = 1; i <= m; i++) {
165             edge[i] = make_pair(INT(), INT());
166             del[i] = false;
167         }
168         for (q = 0;; q++) {
169             a[q].cmd = CHAR();
170             if (a[q].cmd == 'E')
171                 break;
172             a[q].x = INT();
173             if (a[q].cmd == 'D')
174                 del[a[q].x] = true;
175             else {
176                 a[q].k = INT();
177                 if (a[q].cmd == 'C')
178                     AddEdge(a[q].x, a[q].k);
179             }
180         }
181         for (i = 1; i <= n; i++) {
182             spt.NewNode(spt.root, i, 0, cost[first[i]]);
183             first[i] = next[first[i]];
184         }
185         for (i = 1; i <= m; i++) {
186             if (!del[i]) {
187                 x = FindSet(edge[i].first);
188                 y = FindSet(edge[i].second);
189                 if (x != y) {
190                     spt.Join(edge[i].first, edge[i].second);
191                     father[x] = y;
192                 }
193             }
194         }
195         ans = cnt = 0;
196         for (i = q - 1; i >= 0; i--) {
197             if (a[i].cmd == 'Q') {
198                 cnt++;
199                 ans += spt.Query(a[i].x, a[i].k);
200             } else if (a[i].cmd == 'D') {
201                 x = FindSet(edge[a[i].x].first);
202                 y = FindSet(edge[a[i].x].second);
203                 if (x != y) {
204                     spt.Join(edge[a[i].x].first, edge[a[i].x].second);
205                     father[x] = y;
206                 }
207             } else {
208                 spt.Change(a[i].x, cost[first[a[i].x]]);
209                 first[a[i].x] = next[first[a[i].x]];
210             }
211         }
212         printf("Case %d: %lf\n", ca++, ans / cnt);
213     }
214     return 0;
215 }
posted on 2012-08-19 16:31  DrunBee  阅读(837)  评论(0编辑  收藏  举报