HDU 3726 Graph and Queries (离线处理+splay tree)
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
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.
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.
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
Case 2: 16.666667
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
题目首先给出了N个点,M条边的图。每个点有一个对应的权值。
然后下面由三种操作:
1: D X :删掉第X条边。
2: Q X K :查询和X相连的点中 第K大的点的值(K=1表示最大,K=2表示第二大,。。。。)
3: C X V :将点X的权值修改为V
离线处理。
点的权值的变化使用邻接表存下来。
离线后删边当成加边,就是合并。
合并的时候只能把点的个数少的一个个插入
- /* ***********************************************
- Author :kuangbin
- Created Time :2013/8/28 23:05:49
- File Name :F:\2013ACM练习\专题学习\splay_tree_2\HDU3726.cpp
- ************************************************ */
- #include <stdio.h>
- #include <string.h>
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <queue>
- #include <set>
- #include <map>
- #include <string>
- #include <math.h>
- #include <stdlib.h>
- #include <time.h>
- using namespace std;
- #define Key_value ch[ch[root][1]][0]
- const int MAXN = ;
- int pre[MAXN],ch[MAXN][],key[MAXN],size[MAXN];
- int root;
- void NewNode(int &r,int father,int loc,int k)
- {
- r = loc;
- pre[r] = father;
- ch[r][] = ch[r][] = ;
- key[r] = k;
- size[r] = ;
- }
- void push_up(int r)
- {
- size[r] = size[ch[r][]] + size[ch[r][]] + ;
- }
- void Init()
- {
- root = ;
- ch[root][] = ch[root][] = key[root] = size[root] = ;
- pre[root] = ;
- }
- void Rotate(int x,int kind)
- {
- int y = pre[x];
- ch[y][!kind] = ch[x][kind];
- pre[ch[x][kind]] = y;
- if(pre[y])
- ch[pre[y]][ch[pre[y]][]==y] = x;
- pre[x] = pre[y];
- ch[x][kind] = y;
- pre[y] = x;
- push_up(y);
- }
- void Splay(int r,int goal)
- {
- while(pre[r] != goal)
- {
- if(pre[pre[r]] == goal)
- Rotate(r,ch[pre[r]][] == r);
- else
- {
- int y = pre[r];
- int kind = ch[pre[y]][]==y;
- if(ch[y][kind] == r)
- {
- Rotate(r,!kind);
- Rotate(r,kind);
- }
- else
- {
- Rotate(y,kind);
- Rotate(r,kind);
- }
- }
- }
- push_up(r);
- if(goal == ) root = r;
- }
- int Get_kth(int r,int k)
- {
- int t = size[ch[r][]] + ;
- if(t == k)return r;
- if(t > k)return Get_kth(ch[r][],k);
- else return Get_kth(ch[r][],k-t);
- }
- void Insert(int loc,int k)
- {
- int r = root;
- if(r == )
- {
- NewNode(root,,loc,k);
- return;
- }
- while(ch[r][key[r]<k])
- r = ch[r][key[r]<k];
- NewNode(ch[r][key[r]<k],r,loc,k);
- Splay(ch[r][key[r]<k],);
- }
- struct Edge
- {
- int u,v;
- }edge[];
- bool used[];
- //把修改的值建成邻接表
- int to[];
- int next[];
- int head[];
- int tot;
- void add_value(int x,int v)
- {
- to[tot] = v;
- next[tot] = head[x];
- head[x] = tot++;
- }
- struct Query
- {
- char op[];
- int x,y;
- }query[];
- int q_num;
- int F[];
- int find(int x)
- {
- if(F[x] == -)return x;
- else return F[x] = find(F[x]);
- }
- void erase(int r)
- {
- if(!r)return;
- erase(ch[r][]);
- erase(ch[r][]);
- Insert(r,to[head[r]]);
- }
- int Get_Min(int r)
- {
- while(ch[r][])
- {
- r = ch[r][];
- }
- return r;
- }
- //删除根结点
- void Delete()
- {
- if(ch[root][] == || ch[root][] == )
- {
- root = ch[root][] + ch[root][];
- pre[root] = ;
- return;
- }
- int k = Get_Min(ch[root][]);
- Splay(k,root);
- Key_value = ch[root][];
- root = ch[root][];
- pre[ch[root][]] = root;
- pre[root] = ;
- push_up(root);
- }
- void bing(int x,int y)
- {
- int t1 = find(x),t2 = find(y);
- if(t1 == t2)return;
- F[t1] = t2;
- Splay(t1,);
- Splay(t2,);
- if(size[t1] > size[t2])
- swap(t1,t2);
- root = t2;
- erase(t1);
- }
- int main()
- {
- //freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- int N,M;
- int iCase = ;
- while(scanf("%d%d",&N,&M) == )
- {
- if(N == && M == ) break;
- iCase++;
- memset(head,-,sizeof(head));
- tot = ;
- int v;
- for(int i = ;i <= N;i++)
- {
- scanf("%d",&v);
- add_value(i,v);
- }
- for(int i = ;i <= M;i++)
- {
- scanf("%d%d",&edge[i].u,&edge[i].v);
- }
- q_num = ;
- memset(used,false,sizeof(used));
- while(scanf("%s",&query[q_num].op) == )
- {
- if(query[q_num].op[] == 'E')break;
- if(query[q_num].op[] == 'D')
- {
- scanf("%d",&query[q_num].x);
- used[query[q_num].x] = true;
- }
- else if(query[q_num].op[] == 'Q')
- scanf("%d%d",&query[q_num].x,&query[q_num].y);
- else if(query[q_num].op[] == 'C')
- {
- scanf("%d%d",&query[q_num].x,&query[q_num].y);
- add_value(query[q_num].x,query[q_num].y);
- }
- q_num++;
- }
- memset(F,-,sizeof(F));
- for(int i = ;i <= N;i++)
- NewNode(root,,i,to[head[i]]);
- for(int i = ;i <= M;i++)
- if(!used[i])
- bing(edge[i].u,edge[i].v);
- double ans = ;
- int cnt = ;
- for(int i = q_num-; i>= ;i--)
- {
- if(query[i].op[] == 'Q')
- {
- Splay(query[i].x,);
- if(size[root] < query[i].y || query[i].y <= )
- {
- cnt++;
- continue;
- }
- ans += key[Get_kth(root,size[root] - query[i].y + )];
- cnt++;
- }
- else if(query[i].op[] == 'D')
- {
- int tmp = query[i].x;
- bing(edge[tmp].u,edge[tmp].v);
- }
- else if(query[i].op[] == 'C')
- {
- Splay(query[i].x,);
- Delete();
- head[query[i].x] = next[head[query[i].x]];
- Insert(query[i].x,to[head[query[i].x]]);
- }
- }
- if(cnt == )cnt = ;
- printf("Case %d: %.6lf\n",iCase,ans/cnt);
- }
- return ;
- }
HDU 3726 Graph and Queries (离线处理+splay tree)的更多相关文章
- 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(平衡二叉树)(2010 Asia Tianjin Regional Contest)
Description You are given an undirected graph with N vertexes and M edges. Every vertex in this grap ...
- [la P5031&hdu P3726] Graph and Queries
[la P5031&hdu P3726] Graph and Queries Time Limit: 10000/5000 MS (Java/Others) Memory Limit: ...
- 【HDOJ】3726 Graph and Queries
Treap的基础题目,Treap是个挺不错的数据结构. /* */ #include <iostream> #include <string> #include <map ...
- HDU 3436--Queue-jumpers (树状数组 or Splay Tree)
树状数组这个真心想了好久,还是没想出来 %%% www.cppblog.com/Yuan/archive/2010/08/18/123871.html 树状数组求前缀和大于等于k的最大值,第一次看到这 ...
- HDU 4453 Looploop (伸展树splay tree)
Looploop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- splay tree旋转操作 hdu 1890
很神奇的旋转操作. 目前没看到其他数据结构能实现这个功能.平衡树不好处理区间操作,线段树很难旋转.splay tree搞这个就很简单了. 下面用的这个模板跑了700ms,好慢,估计是删除操作太费时了, ...
随机推荐
- springboot配置fastjson后端往前端传输格式化
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.Spri ...
- 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 ...
- IntelliJ IDEA 2018.2.2及以下版本破解方法
破解文件下载地址:https://pan.baidu.com/s/1FKeGekyIHFUWaWi6tk2eEw =========================================== ...
- xss攻击原理与解决方法
概述 XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的,形成了一次有效XSS攻击,一旦攻击成功,它可以获取用户的联系人列 表,然后向联系 ...
- 配置toad远程连接oracle
在oracle服务器上: C:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN目录 文件:listener.ora(10.144.118 ...
- overlay实现容器跨主机通信
本节内容: Docker容器跨主机通信方案 环境信息 升级内核 安装docker 防火墙设置和开启内核转发 安装启动consul 启动Docker 创建overlay network 创建容器 测试容 ...
- JAVA类课后练习
1.Pg168--2 package com.hanqi; import java.util.Scanner; public class Rectangle { Rectangle() { //完成初 ...
- 结合Python代码介绍音符起始点检测 (onset detection)
本文由 meelo 原创,请务必以链接形式注明 本文地址 音符起始点检测介绍 音符起始点检测(onset detection)是音乐信号处理中非常重要的一个算法.节拍和速度(tempo)的检测都会基于 ...
- drools7 (二、agenda-group 的使用)
几个关键点: 1. 如果没有指定agenda-group 则默认把所有未指定agenda-group的 rules 都执行一遍 2. 如果指定了agenda-group 使用的时候必须指定该name才 ...
- jenkins备份与恢复
jenkins这里我通过thinbackup插件进行对jenkins的配置备份与恢复 1丶安装thinbackup插件 2丶系统管理选择thinbackup插件 3丶创建备份目录 mkdir /bac ...