Graph and Queries

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1467    Accepted Submission(s): 301

Problem Description
You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You're also given a sequence of operations and you need to process them as requested. Here's a list of the possible operations that you might encounter:
1)  Deletes an edge from the graph.
The format is [D X], where X is an integer from 1 to M, indicating the ID of the edge that you should delete. It is guaranteed that no edge will be deleted more than once.
2)  Queries the weight of the vertex with K-th maximum value among all vertexes currently connected with vertex X (including X itself).
The format is [Q X K], where X is an integer from 1 to N, indicating the id of the vertex, and you may assume that K will always fit into a 32-bit signed integer. In case K is illegal, the value for that query will be considered as undefined, and you should return 0 as the answer to that query.
3)  Changes the weight of a vertex.
The format is [C X V], where X is an integer from 1 to N, and V is an integer within the range [-106, 106].

The operations end with one single character, E, which indicates that the current case has ended.
For simplicity, you only need to output one real number - the average answer of all queries.

 
Input
There are multiple test cases in the input file. Each case starts with two integers N and M (1 <= N <= 2 * 104, 0 <= M <= 6 * 104), the number of vertexes in the graph. The next N lines describes the initial weight of each vertex (-106 <= weight[i] <= 106). The next part of each test case describes the edges in the graph at the beginning. Vertexes are numbered from 1 to N. The last part of each test case describes the operations to be performed on the graph. It is guaranteed that the number of query operations [Q X K] in each case will be in the range [1, 2 * 105], and there will be no more than 2 * 105 operations that change the values of the vertexes [C X V].

There will be a blank line between two successive cases. A case with N = 0, M = 0 indicates the end of the input file and this case should not be processed by your program.

 
Output
For each test case, output one real number – the average answer of all queries, in the format as indicated in the sample output. Please note that the result is rounded to six decimal places.
 
Sample Input
3 3
10
20
30
1 2
2 3
1 3
D 3
Q 1 2
Q 2 1
D 2
Q 3 2
C 1 50
Q 1 1
E

3 3
10
20
20
1 2
2 3
1 3
Q 1 1
Q 1 2
Q 1 3
E

0 0

 
Sample Output
Case 1: 25.000000
Case 2: 16.666667

Hint

For the first sample:
D 3 -- deletes the 3rd edge in the graph (the remaining edges are (1, 2) and (2, 3))
Q 1 2 -- finds the vertex with the second largest value among all vertexes connected with 1. The answer is 20.
Q 2 1 -- finds the vertex with the largest value among all vertexes connected with 2. The answer is 30.
D 2 -- deletes the 2nd edge in the graph (the only edge left after this operation is (1, 2))
Q 3 2 -- finds the vertex with the second largest value among all vertexes connected with 3. The answer is 0 (Undefined).
C 1 50 -- changes the value of vertex 1 to 50.
Q 1 1 -- finds the vertex with the largest value among all vertex connected with 1. The answer is 50.
E -- This is the end of the current test case. Four queries have been evaluated, and the answer to this case is (20 + 30 + 0 + 50) / 4 = 25.000.

For the second sample, caution about the vertex with same weight:
Q 1 1 – the answer is 20
Q 1 2 – the answer is 20
Q 1 3 – the answer is 10

 
Source
 
Recommend
zhouzeyong
 

题目首先给出了N个点,M条边的图。每个点有一个对应的权值。

然后下面由三种操作:

1: D X :删掉第X条边。

2: Q  X  K :查询和X相连的点中 第K大的点的值(K=1表示最大,K=2表示第二大,。。。。)

3: C X V :将点X的权值修改为V

离线处理。

点的权值的变化使用邻接表存下来。

离线后删边当成加边,就是合并。

合并的时候只能把点的个数少的一个个插入

  1. /* ***********************************************
  2. Author :kuangbin
  3. Created Time :2013/8/28 23:05:49
  4. File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU3726.cpp
  5. ************************************************ */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <iostream>
  10. #include <algorithm>
  11. #include <vector>
  12. #include <queue>
  13. #include <set>
  14. #include <map>
  15. #include <string>
  16. #include <math.h>
  17. #include <stdlib.h>
  18. #include <time.h>
  19. using namespace std;
  20.  
  21. #define Key_value ch[ch[root][1]][0]
  22. const int MAXN = ;
  23. int pre[MAXN],ch[MAXN][],key[MAXN],size[MAXN];
  24. int root;
  25.  
  26. void NewNode(int &r,int father,int loc,int k)
  27. {
  28. r = loc;
  29. pre[r] = father;
  30. ch[r][] = ch[r][] = ;
  31. key[r] = k;
  32. size[r] = ;
  33. }
  34. void push_up(int r)
  35. {
  36. size[r] = size[ch[r][]] + size[ch[r][]] + ;
  37. }
  38.  
  39. void Init()
  40. {
  41. root = ;
  42. ch[root][] = ch[root][] = key[root] = size[root] = ;
  43. pre[root] = ;
  44. }
  45.  
  46. void Rotate(int x,int kind)
  47. {
  48. int y = pre[x];
  49. ch[y][!kind] = ch[x][kind];
  50. pre[ch[x][kind]] = y;
  51. if(pre[y])
  52. ch[pre[y]][ch[pre[y]][]==y] = x;
  53. pre[x] = pre[y];
  54. ch[x][kind] = y;
  55. pre[y] = x;
  56. push_up(y);
  57. }
  58. void Splay(int r,int goal)
  59. {
  60. while(pre[r] != goal)
  61. {
  62. if(pre[pre[r]] == goal)
  63. Rotate(r,ch[pre[r]][] == r);
  64. else
  65. {
  66. int y = pre[r];
  67. int kind = ch[pre[y]][]==y;
  68. if(ch[y][kind] == r)
  69. {
  70. Rotate(r,!kind);
  71. Rotate(r,kind);
  72. }
  73. else
  74. {
  75. Rotate(y,kind);
  76. Rotate(r,kind);
  77. }
  78. }
  79. }
  80. push_up(r);
  81. if(goal == ) root = r;
  82. }
  83. int Get_kth(int r,int k)
  84. {
  85. int t = size[ch[r][]] + ;
  86. if(t == k)return r;
  87. if(t > k)return Get_kth(ch[r][],k);
  88. else return Get_kth(ch[r][],k-t);
  89. }
  90.  
  91. void Insert(int loc,int k)
  92. {
  93. int r = root;
  94. if(r == )
  95. {
  96. NewNode(root,,loc,k);
  97. return;
  98. }
  99. while(ch[r][key[r]<k])
  100. r = ch[r][key[r]<k];
  101. NewNode(ch[r][key[r]<k],r,loc,k);
  102. Splay(ch[r][key[r]<k],);
  103. }
  104.  
  105. struct Edge
  106. {
  107. int u,v;
  108. }edge[];
  109. bool used[];
  110.  
  111. //把修改的值建成邻接表
  112. int to[];
  113. int next[];
  114. int head[];
  115. int tot;
  116.  
  117. void add_value(int x,int v)
  118. {
  119. to[tot] = v;
  120. next[tot] = head[x];
  121. head[x] = tot++;
  122. }
  123.  
  124. struct Query
  125. {
  126. char op[];
  127. int x,y;
  128. }query[];
  129. int q_num;
  130.  
  131. int F[];
  132.  
  133. int find(int x)
  134. {
  135. if(F[x] == -)return x;
  136. else return F[x] = find(F[x]);
  137. }
  138.  
  139. void erase(int r)
  140. {
  141. if(!r)return;
  142. erase(ch[r][]);
  143. erase(ch[r][]);
  144. Insert(r,to[head[r]]);
  145. }
  146. int Get_Min(int r)
  147. {
  148. while(ch[r][])
  149. {
  150. r = ch[r][];
  151. }
  152. return r;
  153. }
  154.  
  155. //删除根结点
  156. void Delete()
  157. {
  158. if(ch[root][] == || ch[root][] == )
  159. {
  160. root = ch[root][] + ch[root][];
  161. pre[root] = ;
  162. return;
  163. }
  164. int k = Get_Min(ch[root][]);
  165. Splay(k,root);
  166. Key_value = ch[root][];
  167. root = ch[root][];
  168. pre[ch[root][]] = root;
  169. pre[root] = ;
  170. push_up(root);
  171. }
  172. void bing(int x,int y)
  173. {
  174. int t1 = find(x),t2 = find(y);
  175. if(t1 == t2)return;
  176. F[t1] = t2;
  177. Splay(t1,);
  178. Splay(t2,);
  179. if(size[t1] > size[t2])
  180. swap(t1,t2);
  181. root = t2;
  182. erase(t1);
  183. }
  184. int main()
  185. {
  186. //freopen("in.txt","r",stdin);
  187. //freopen("out.txt","w",stdout);
  188. int N,M;
  189. int iCase = ;
  190. while(scanf("%d%d",&N,&M) == )
  191. {
  192. if(N == && M == ) break;
  193. iCase++;
  194. memset(head,-,sizeof(head));
  195. tot = ;
  196. int v;
  197. for(int i = ;i <= N;i++)
  198. {
  199. scanf("%d",&v);
  200. add_value(i,v);
  201. }
  202. for(int i = ;i <= M;i++)
  203. {
  204. scanf("%d%d",&edge[i].u,&edge[i].v);
  205. }
  206. q_num = ;
  207. memset(used,false,sizeof(used));
  208. while(scanf("%s",&query[q_num].op) == )
  209. {
  210. if(query[q_num].op[] == 'E')break;
  211. if(query[q_num].op[] == 'D')
  212. {
  213. scanf("%d",&query[q_num].x);
  214. used[query[q_num].x] = true;
  215. }
  216. else if(query[q_num].op[] == 'Q')
  217. scanf("%d%d",&query[q_num].x,&query[q_num].y);
  218. else if(query[q_num].op[] == 'C')
  219. {
  220. scanf("%d%d",&query[q_num].x,&query[q_num].y);
  221. add_value(query[q_num].x,query[q_num].y);
  222. }
  223. q_num++;
  224. }
  225. memset(F,-,sizeof(F));
  226. for(int i = ;i <= N;i++)
  227. NewNode(root,,i,to[head[i]]);
  228.  
  229. for(int i = ;i <= M;i++)
  230. if(!used[i])
  231. bing(edge[i].u,edge[i].v);
  232.  
  233. double ans = ;
  234. int cnt = ;
  235.  
  236. for(int i = q_num-; i>= ;i--)
  237. {
  238. if(query[i].op[] == 'Q')
  239. {
  240. Splay(query[i].x,);
  241. if(size[root] < query[i].y || query[i].y <= )
  242. {
  243. cnt++;
  244. continue;
  245. }
  246. ans += key[Get_kth(root,size[root] - query[i].y + )];
  247. cnt++;
  248. }
  249. else if(query[i].op[] == 'D')
  250. {
  251. int tmp = query[i].x;
  252. bing(edge[tmp].u,edge[tmp].v);
  253. }
  254. else if(query[i].op[] == 'C')
  255. {
  256. Splay(query[i].x,);
  257. Delete();
  258. head[query[i].x] = next[head[query[i].x]];
  259. Insert(query[i].x,to[head[query[i].x]]);
  260. }
  261. }
  262. if(cnt == )cnt = ;
  263. printf("Case %d: %.6lf\n",iCase,ans/cnt);
  264. }
  265. return ;
  266. }

HDU 3726 Graph and Queries (离线处理+splay tree)的更多相关文章

  1. HDU 3726 Graph and Queries treap树

    题目来源:HDU 3726 Graph and Queries 题意:见白书 思路:刚学treap 參考白皮书 #include <cstdio> #include <cstring ...

  2. HDU 3726 Graph and Queries 平衡树+前向星+并查集+离线操作+逆向思维 数据结构大综合题

    Graph and Queries Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. HDU 3726 Graph and Queries(平衡二叉树)(2010 Asia Tianjin Regional Contest)

    Description You are given an undirected graph with N vertexes and M edges. Every vertex in this grap ...

  4. [la P5031&hdu P3726] Graph and Queries

    [la P5031&hdu P3726] Graph and Queries Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: ...

  5. 【HDOJ】3726 Graph and Queries

    Treap的基础题目,Treap是个挺不错的数据结构. /* */ #include <iostream> #include <string> #include <map ...

  6. HDU 3436--Queue-jumpers (树状数组 or Splay Tree)

    树状数组这个真心想了好久,还是没想出来 %%% www.cppblog.com/Yuan/archive/2010/08/18/123871.html 树状数组求前缀和大于等于k的最大值,第一次看到这 ...

  7. HDU 4453 Looploop (伸展树splay tree)

    Looploop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. HDU 1890 Robotic Sort (splay tree)

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  9. splay tree旋转操作 hdu 1890

    很神奇的旋转操作. 目前没看到其他数据结构能实现这个功能.平衡树不好处理区间操作,线段树很难旋转.splay tree搞这个就很简单了. 下面用的这个模板跑了700ms,好慢,估计是删除操作太费时了, ...

随机推荐

  1. springboot配置fastjson后端往前端传输格式化

    import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.Spri ...

  2. MyBatis3.4.0以上的分页插件错误:Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.stateme

    错误: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named p ...

  3. IntelliJ IDEA 2018.2.2及以下版本破解方法

    破解文件下载地址:https://pan.baidu.com/s/1FKeGekyIHFUWaWi6tk2eEw =========================================== ...

  4. xss攻击原理与解决方法

    概述 XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的,形成了一次有效XSS攻击,一旦攻击成功,它可以获取用户的联系人列 表,然后向联系 ...

  5. 配置toad远程连接oracle

    在oracle服务器上: C:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN目录 文件:listener.ora(10.144.118 ...

  6. overlay实现容器跨主机通信

    本节内容: Docker容器跨主机通信方案 环境信息 升级内核 安装docker 防火墙设置和开启内核转发 安装启动consul 启动Docker 创建overlay network 创建容器 测试容 ...

  7. JAVA类课后练习

    1.Pg168--2 package com.hanqi; import java.util.Scanner; public class Rectangle { Rectangle() { //完成初 ...

  8. 结合Python代码介绍音符起始点检测 (onset detection)

    本文由 meelo 原创,请务必以链接形式注明 本文地址 音符起始点检测介绍 音符起始点检测(onset detection)是音乐信号处理中非常重要的一个算法.节拍和速度(tempo)的检测都会基于 ...

  9. drools7 (二、agenda-group 的使用)

    几个关键点: 1. 如果没有指定agenda-group 则默认把所有未指定agenda-group的 rules 都执行一遍 2. 如果指定了agenda-group 使用的时候必须指定该name才 ...

  10. jenkins备份与恢复

    jenkins这里我通过thinbackup插件进行对jenkins的配置备份与恢复 1丶安装thinbackup插件 2丶系统管理选择thinbackup插件 3丶创建备份目录 mkdir /bac ...