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,好慢,估计是删除操作太费时了, ...
随机推荐
- python基础--os模块和sys模块
os模块提供对操作系统进行调用的接口 # -*- coding:utf-8 -*-__author__ = 'shisanjun' import os print(os.getcwd())#获取当前工 ...
- python并行计算(持续更新)
工作中需要对tensorflow 的一个predict结果加速,利用python中的线程池 def getPPLs(tester,datas): for line in datas: tester(l ...
- yum命令安装软件时,出现--centos 7 安装apache 出现 Could not resolve host: mirrorlist.centos.org; 未知的错误"--CentOS网络设置 couldn't resolve host 'mirrorlist.centos.org问题解决
CentOS网络设置 couldn't resolve host 'mirrorlist.centos.org问题解决 今天在虚拟机上安装完CentOS6.5之后,首次使用时yum命令安装软件时,出现 ...
- [Torch]的安装
1 安装Torch 本文介绍Torch7的安装方法,因为本人安装Torch前安装了caffe,所以可能CUDA.cudnn.Blas等Torch可能需要用来的库的安装就不再重复介绍了,相关依赖出现问题 ...
- 动态规划面试题基础合集1--数学三角形,LIS , LCS, CSD
动态规划的一般思路是分为四步,即:寻找最优子结构.递归定义最优子结构.自底向上求解最优子结构和构造最优解. 接下来我列举出几个常见的动态规划面试题进行说明. (1)数学三角形:比较简单,直接贴一个我看 ...
- 【LOJ】#2574. 「TJOI2018」智力竞赛
题解 二分答案 求最小路径点覆盖 由于这里最小路径点覆盖,点是可重的,用floyd求出传递闭包(也就是求出,哪两点之间是可达的) 最后用这个floyd求出的数组建出一个新图,在这个图上跑普通的最小路径 ...
- 【POJ】2449.Remmarguts' Date(K短路 n log n + k log k + m算法,非A*,论文算法)
题解 (搬运一个原来博客的论文题) 抱着板题的心情去,结果有大坑 就是S == T的时候也一定要走,++K 我发现按照论文写得\(O(n \log n + m + k \ log k)\)算法没有玄学 ...
- thinkphp图像的裁剪、缩放、加水印
ThinkPHP 图片处理函数,需要文字水印字体,可在windows下 控制面板 > 大图标(右上角) > 字体 找到需要的字体 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- 洛谷P3527 [POI2011]MET-Meteors [整体二分]
题目传送门 Meteors 格式难调,题面就不妨放了. 分析: 一道整体二分的练手题. 就是一般的整体二分的套路,但是要注意,将修改和询问加入队列的时候要先加修改再加询问.另外,博主代码打得太丑,常数 ...
- React Native网络编程之Fetch
目录 1.前言 2.什么是Fetch 3.最简单的应用 4.支持的请求参数 - 4.1. 参数详讲 - 4.2. 示例 5.请求错误与异常处理 1. 前言 网络请求是开发APP中不可或缺的一部 ...