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

离线处理。

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

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

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

 /* ***********************************************
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)的更多相关文章

  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. Densely Connected Convolutional Networks 论文阅读

    毕设终于告一段落,传统方法的视觉做得我整个人都很奔溃,终于结束,可以看些搁置很久的一些论文了,嘤嘤嘤 Densely Connected Convolutional Networks 其实很早就出来了 ...

  2. 激活Win10内置版Linux (ubuntu)

    微软自从14316版本后,就开始原生支持Linux  Bash命令行. 1.首先到系统设置——更新和安全——针对开发人员——选择开发者模式. 2.控制面板→程序和功能→启用或关闭Windows功能,勾 ...

  3. 使用Emacs:帮助篇

    当你打开emacs并认真阅读“快速指南”后,你已经知道用C-x C-f打开文件,用C-x C-s保存文件,用C-x C-c退出emacs,可以在emacs中生存了.这里把Tutorial.cn中出现的 ...

  4. Ansible介绍及安装部署

    本节内容: 运维工具 Ansible特性 Ansible架构图和核心组件 安装Ansible 演示使用示例 一.运维工具 作为一个Linux运维人员,需要了解大量的运维工具,并熟知这些工具的差异,能够 ...

  5. 使用mongo-java-driver-3.0.2连接MongoDB数据库

    这里使用的mongodb的java驱动版本是:3.0.2,文件名mongo-java-driver-3.0.2.jar  博客本地下载下载网址(也可以下载其它版本):http://central.ma ...

  6. 【BZOJ】4671: 异或图

    题解 写完之后开始TTTTTTT--懵逼 这道题我们考虑一个东西叫容斥系数啊>< 这个是什么东西呢 也就是\(\sum_{i = 1}^{m}\binom{m}{i}f_{i} = [m ...

  7. LAMP环境使用Composer安装Laravel

    安装Composer 因为使用的Ubuntu服务器,所以我们使用apt安装: 1 $ sudo apt install composer 安装Laravel 首先创建一个项目目录,进入新目录使用Com ...

  8. Unity:控制粒子特效的移动方向

    前几天在项目中遇到一个问题,需求是界面中先展示一段闪光特效,停顿一段时间后特效飞往一个固定的位置然后消失,类似于跑酷游戏吃到金币后金币飞往固定的金币数值显示框那种效果(具体是通过特效来实现还是直接通过 ...

  9. Eclipse导入SVN项目的三种方式

    Eclipse导入SVN项目的三种方式 一.直接Import导入: 1.点击 File --> Import,进入导入项目窗口 2.选择从SVN检出项目,点击Next 3.选择创建新的资源库位置 ...

  10. Javascript和JQuery之间的联系

    一.Js对象和Jquery对象之间的相互转化1.Js对象转化为Jquery对象 var p = document.getElementById('p'); var $obj = $(p); 2.Jqu ...