【HDU】3726 Graph and Queries

  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 }

你可能感兴趣的:(Graph)