[la P5031&hdu P3726] Graph and Queries
[la P5031&hdu P3726] Graph and Queries
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem DescriptionYou 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.InputThere 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.
OutputFor 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 0Sample Output
Case 1: 25.000000
Case 2: 16.666667
HintFor 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
这题很经典,但又有坑——
首先,这题涉及到删边。
删边不方便,这时我们自然会想到删边的反面——加边。
那我们就可以倒着来操作,方便D操作。
但同时,每个点的权值也要从终状态到始状态来变化。
然后,我们就可以用并查集来实现加边操作,就把一条边加上了。
当然,最终状态也存在一些边,刚开始也要连上。
然后,Q操作要求我们查询连通块内第k大,如果k不合法则返回0。
第k大可以用一个平衡树来维护,我用了treap名次树,方便一些。
但是,注意这里的第k大可能有些定义上的模糊,我最后几发就被坑了。
似乎没有人是加了一个“相同点的个数”这个域A掉了的,我也是改用lrj的写法才A了的,这个需要注意一下。
然后第k大不合法,有可能是超出连通块大小,也有可能k<1。
对于C操作,就相当于再某个连通块中先删掉一个点权为w1的点,再加入一个点权为为w2的点,w1,w2就不多说了。
但是无论如何,都要注意,点权的变化顺序是怎样的。
如果就这样写——就T了。
为什么呢?可能会有数据卡“加边”这一个操作。在这里我们需要合并两颗平衡树。
怎么合并?我们采用启发式合并。就是从节点数小的向节点数大的树并。
怎么证明这样操作的时间复杂度是对的?假设树T1有n1个节点,T2有n2个节点,且n1>n2。
那么显然,我们会把T2并到T1里面。复杂度接近于O(n2logn1)。
由于对于原来T2里的每个点,它所在的树的大小至少增大了一倍,所以对于任意节点,它会被移动不超过logn次。
所以总复杂度是O(n(logn)^2)的。
然后。。通过这个题目,学到了treap的启发式合并和删除。。
code:
%:pragma GCC optimize() #include<bits/stdc++.h> #define LL long long using namespace std; ,M=,Q=; int n,m,q,cas,w[N],fa[N]; char ch; LL ans,cnt; bool vis[M]; struct edg {int x,y;}a[M]; struct opt {char t; int x,k;}o[Q]; class node { private: public: ]; node() {ch[]=ch[]=;} inline void newnode(node* &cu,int v) { cu=; } inline void update(node* &cu) { cu->s=; ]!=) cu->s+=cu->ch[]->s; ]!=) cu->s+=cu->ch[]->s; } inline void rotate(node* &cu,bool dr) { node* tmp=cu->ch[dr^]->ch[dr]; cu->ch[dr^]->ch[dr]=cu; cu=cu->ch[dr^]; cu->ch[dr]->ch[dr^]=tmp; update(cu->ch[dr]); update(cu); } inline void insert(node* &cu,int v) { ) {newnode(cu,v); return;} bool p=v<=cu->v; insert(cu->ch[p],v); ); else update(cu); } inline void remove(node* &cu,int v) { ) return; if (v==cu->v) { ]==&&cu->ch[]==) {cu=; return;} ]==||cu->ch[]==) { cu=cu->ch[]==?cu->ch[]:cu->ch[]; return; } ]->k>cu->ch[]->k; rotate(cu,p^); remove(cu->ch[p^],v); update(cu); return; } int p=v<=cu->v; remove(cu->ch[p],v); update(cu); } inline int kth(node* cu,int k) { ||cu==) ; ]!=)?cu->ch[]->s:; ) return cu->v; ) ],k); ],k-s-); } inline void merge(node* &major,node* &minor) { insert(major,minor->v); ]!=) merge(major,minor->ch[]); ]!=) merge(major,minor->ch[]); ; } inline void clear(node* &cu) { ]!=) clear(cu->ch[]); ]!=) clear(cu->ch[]); ; } }t,*root[N]; inline int read() { ,f=; ch=getchar(); ') {if (ch=='-') f=-f; ch=getchar();} +ch-',ch=getchar(); return x*f; } inline char readch() { while (ch<'A'||ch>'Z') ch=getchar(); return ch; } inline int get(int x) { return fa[x]==x?x:fa[x]=get(fa[x]); } int main() { srand(),cas=; while (scanf("%d%d",&n,&m)!=EOF&&n) { ans=cnt=q=,memset(vis,,sizeof vis); ,x; i<=n; i++) w[i]=read(); ; i<=m; i++) a[i].x=read(),a[i].y=read(); for ( ; ; ) { o[++q].t=readch(); if (o[q].t=='E') break; o[q].x=read(); if (o[q].t!='D') o[q].k=read(); } ,v; i<q; i++) { ; if (o[i].t=='C') swap(w[o[i].x],o[i].k); } ; i<=n; i++) { fa[i]=i; ) t.clear(root[i]); } ,x,y; i<=m; i++) if (!vis[i]) { x=get(a[i].x),y=get(a[i].y); if (x==y) continue; else fa[x]=y; } ; i<=n; i++) t.insert(root[get(i)],w[i]); ; i--) { if (o[i].t=='D') { x=get(a[o[i].x].x),y=get(a[o[i].x].y); if (x==y) continue; if (root[x]->s>root[y]->s) fa[y]=x,t.merge(root[x],root[y]); else fa[x]=y,t.merge(root[y],root[x]); }else if (o[i].t=='Q'){ cnt++,ans+=(LL)t.kth(root[get(o[i].x)],o[i].k); } else if (o[i].t=='C') { t.remove(root[x=get(o[i].x)],w[o[i].x]); t.insert(root[x],o[i].k); w[o[i].x]=o[i].k; } } printf("Case %d: %.6lf\n",++cas,1.0*ans/cnt); } ; }
[la P5031&hdu P3726] Graph and Queries的更多相关文章
- HDU 3726 Graph and Queries treap树
题目来源:HDU 3726 Graph and Queries 题意:见白书 思路:刚学treap 參考白皮书 #include <cstdio> #include <cstring ...
- HDU 3726 Graph and Queries 平衡树+前向星+并查集+离线操作+逆向思维 数据结构大综合题
Graph and Queries Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 3726 Graph and Queries (离线处理+splay tree)
Graph and Queries Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 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 ...
- LA - 5031 - Graph and Queries
题意:一个N个点(编号从1开始),M条边的无向图(编号从1开始),有3种操作: D X:把编号为X的边删了: Q X K:查询编号为X的结点所在连通分量第K大的元素: C X V:将编号为X的结点的权 ...
- LA 5031 Graph and Queries —— Treap名次树
离线做法,逆序执行操作,那么原本的删除边的操作变为加入边的操作,用名次树维护每一个连通分量的名次,加边操作即是连通分量合并操作,每次将结点数小的子树向结点数大的子树合并,那么单次合并复杂度O(n1lo ...
- hdu 5412 CRB and Queries
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5412 CRB and Queries Description There are $N$ boys i ...
- HDU 4034 Graph(Floyd变形——逆向判断)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4034 Problem Description Everyone knows how to calcu ...
- HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5412 Problem Description There are N boys in CodeLan ...
随机推荐
- 解决 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 问题
https://blog.csdn.net/weixin_41196185/article/details/81114226 今天在启动vue项目的时候报了这样一个错误 观察到关键词是 FATAL E ...
- Docker 推送镜像到hub.docker
1.Docker镜像文件:lails.server.demo:1.0, 2.登录Docker:docker login[根据提示输入用户名/密码] 3.执行:docker push lails.ser ...
- input 输入速度和方向判断、搜索功能的延迟请求
1.input 输入速度和方向判断 var wxApp = {} wxApp.click = function (str,speed) { var lastInput = { d: "&qu ...
- 雾霾天出行,如何精确避开“雷区”?2016 SODA数据侠十强
(2016年参加了上海 SODA 竞赛,进入前十,最终获得上海市的两个奖项.) ▍跟踪雾霾,仅靠零星的监测点数据怎么行? 如果雾霾短期内没有办法彻底根治,我们可以做什么,把环境污染物对人的影响尽可能降 ...
- Docket 使用命令
Docket 使用命令 查 # 查询当前可以下载的镜像 docker search httpd |_ NAME:镜像仓库源的名称 |_ DESCRIPTION:镜像的描述 |_ OFFICIAL:是 ...
- Shell 解释器初识
1.脚本文件要以.sh结尾,第一行要跟#!/bin/bash解释器. 2.运行shell脚本. (1)添加权限:可以加x执行权限,./123.sh (2)命令执行:bash 123.sh,sh 123 ...
- activiti5/6 系列之--BpmnModel使用
BpmnModel对象,是activiti动态部署中很重要的一个对象,如果BpmnModel对象不能深入的理解,那可能如果自己需要开发一套流程设计器,使用bpmn-js使用前端或者C/S展现流程流转而 ...
- -bash: xhost: command not found
参考自:http://blog.csdn.net/csdnones/article/details/51513163,感谢原作者解决了我的问题. 执行xhost +,报以下错误,原因是因未没有安装相关 ...
- 运行软件出现:模块“msvcp110.dll”已加载,但找不到入口点DllRegister
根据百度大多数回答来说 1:先是出现 无法启动程序,因为计算机丢失mfc110.dll 尝试重新安装该程序以解决问题 错误处理:下载或者在别人电脑上拷一份 如:'msvcp110.dll‘ 这类文 ...
- Not supported for DML operations
问题原因 缺失@Modifying注解 问题解决 在自定义的修改方法(delete.update)上面除了@Transactional注解和@Query还需要@Modifying注解 Bug重现 or ...