题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3726

题意:n个点m条边的一张无向图,每个点有一个权值, 有3中操作。

D X 删除第X条边

Q X K 计算与X点相连所有点中第k大的权值

C X V把X的权值改为 V

输出 Q次询问的平均值

大白上的例题, 离线处理,把所有操作 反过来处理,,这样删边变成了 加边,,瞬间好处理多了。。细节也有很多。

 #include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 2e4+;
int n, m, val[maxn];
int pa[maxn];
void init()
{
for (int i = ; i <= n; i++)
{
pa[i] = i;
}
}
int find(int x)
{
return pa[x] = (pa[x] == x ? x : find(pa[x]));
}
struct Node
{
Node* ch[];
int key, r, siz;
Node (int x)
{
key = x;
siz = ;
ch[] = ch[] = NULL;
r = rand();
}
bool operator < (const Node &rhs)const
{
return r < rhs.r;
}
int cmp(int x)
{
if (x == key)
return -;
return x < key ? : ;
}
void maintain()
{
siz = ;
if (ch[] != NULL)
siz += ch[] -> siz;
if (ch[] != NULL)
siz += ch[] -> siz;
}
};
void rotate(Node* &root, int d)
{
Node* tmp = root -> ch[d^];
root -> ch[d^] = tmp -> ch[d];
tmp -> ch[d] = root;
root -> maintain();
tmp -> maintain();
root = tmp;
}
void insert(Node* &root, int x)
{
if (root == NULL)
root = new Node (x);
else
{
int d = x < root -> key ? : ;
insert (root ->ch[d], x);
if (root -> ch[d] -> r > root -> r)
rotate(root, d^); }
root -> maintain();
}
void dele(Node* &root, int x)
{
int d = root -> cmp(x);
if (d == -)
{
Node* tmp = root;
if (root -> ch[] != NULL && root -> ch[] != NULL)
{
int d1 = (root -> ch[] -> r > root -> ch[] -> r ? : );
rotate(root, d1^);
dele(root -> ch[d1^], x);
}
else
{
if (root -> ch[] == NULL)
root = root -> ch[];
else
root = root -> ch[];
delete tmp;
}
}
else
dele(root->ch[d], x);
if (root != NULL)
root -> maintain();
}
int Get_kth(Node* root, int k)
{
if (root == NULL || k <= || root -> siz < k)
return ;
int s = root -> ch[] == NULL ? : root -> ch[] -> siz;
if (s + == k)
return root -> key;
if (s + > k)
return Get_kth(root -> ch[], k);
else
return Get_kth(root -> ch[], k-s-); }
Node* root[maxn];
void merge_tree(Node* &src, Node* &fa)
{
if (src -> ch[] != NULL)
merge_tree(src -> ch[], fa);
if (src -> ch[] != NULL)
merge_tree(src -> ch[], fa);
insert(fa, src -> key);
delete src;
src = NULL;
}
void remove_tree(Node* &root)
{
if (root -> ch[] != NULL)
remove_tree(root -> ch[]);
if (root -> ch[] != NULL)
remove_tree(root -> ch[]);
delete root;
root = NULL;
}
struct
{
int x, y;
bool is_del;
} e[ * maxn];
struct
{
int type, x, p;
} Q[maxn*];
void add_edge(int idx)
{
int fx = find(e[idx].x);
int fy = find(e[idx].y);
if (fx != fy)
{
if (root[fx] -> siz > root[fy] -> siz)
{
pa[fy] = fx;
merge_tree(root[fy], root[fx]);
}
else
{
pa[fx] = fy;
merge_tree(root[fx], root[fy]); }
} }
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int cas = ;
while (~ scanf ("%d%d",&n, &m))
{
if (n == && m == )
break;
for (int i = ; i < n; i++)
{
scanf ("%d", val + + i);
}
for (int i = ; i <= m; i++)
{
scanf ("%d%d", &e[i].x, &e[i].y);
e[i].is_del = false;
}
char op[];
int tot = ;
while (scanf ("%s",op) && op[] != 'E')
{
if (op[] == 'D')
{
scanf ("%d", &Q[tot].x);
Q[tot++].type = ;
e[Q[tot-].x].is_del = true;
}
if (op[] == 'Q')
{
scanf ("%d%d", &Q[tot].x, &Q[tot].p);
Q[tot++].type = ;
}
if (op[] == 'C')
{
int v;
scanf ("%d%d", &Q[tot].x, &v);
Q[tot].p = val[Q[tot].x];
val[Q[tot].x] = v;
Q[tot++].type = ;
}
}
init();
for (int i = ; i < n; i++)
{
if (root[i+] != NULL)
remove_tree(root[i+]);
root[i+] = new Node (val[i+]);
}
for (int i = ; i < m; i++)
{
if (e[i+].is_del == false)
add_edge(i+);
}
ll ans1 = , ans2 = ;
for (int i = tot - ; i >= ; i--)
{
if (Q[i].type == )
{
add_edge(Q[i].x);
}
if (Q[i].type == )
{
ans1 += Get_kth(root[find(Q[i].x)], Q[i].p);
ans2 ++;
}
if (Q[i].type == )
{
int father = find(Q[i].x);
dele (root[father], val[Q[i].x]);
insert (root[father], Q[i].p);
val[Q[i].x] = Q[i].p;
}
}
printf("Case %d: %.6f\n", cas++, 1.0*ans1 / ans2);
}
return ;
}

HDU3726---Graph and Queries 离线处理+Treap的更多相关文章

  1. [HDU3726]Graph and Queries

    Problem 给你一张图,点的权值,边和几个操作: D x: 删除第x条边 Q x y: 询问包含x的联通块中权值第y大的权值 C x y: 将x这个点的权值改为y Solution 一看就要离线处 ...

  2. uvalive 5031 Graph and Queries 名次树+Treap

    题意:给你个点m条边的无向图,每个节点都有一个整数权值.你的任务是执行一系列操作.操作分为3种... 思路:本题一点要逆向来做,正向每次如果删边,复杂度太高.逆向到一定顺序的时候添加一条边更容易.详见 ...

  3. HDU 3726 Graph and Queries (离线处理+splay tree)

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

  4. HDU 3726 Graph and Queries treap树

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

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

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

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

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

  7. UVaLive 5031 Graph and Queries (Treap)

    题意:初始时给出一个图,每个点有一个权值,三种操作:(1)删除某个边:(2)修改每个点的权值:(3)询问与节点x在一个连通分量中所有点的第K大的权值. 析:首先是要先离线,然后再倒着做,第一个操作就成 ...

  8. UVALive 5031 Graph and Queries (Treap)

    删除边的操作不容易实现,那么就先离线然后逆序来做. 逆序就变成了合并,用并存集判断连通,用Treap树来维护一个连通分量里的名次. Treap = Tree + Heap.用一个随机的优先级来平衡搜索 ...

  9. UVALive5031 Graph and Queries(Treap)

    反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...

随机推荐

  1. oracle中LAG()和LEAD()等分析统计函数的使用方法(统计月增长率)

    LAG()和LEAD()统计函数能够在一次查询中取出同一字段的前N行的数据和后N行的值.这样的操作能够使用对同样表的表连接来实现,只是使用LAG和 LEAD有更高的效率.下面整理的LAG()和LEAD ...

  2. 使用CSS为内容设定特定的鼠标样式(cursor)介绍

    相信大家都知道我们的鼠标在网页中不同的元素中有不同的显示(例如 a 元素就显示为“箭头指针”),但是其实我们还可以自定义这些有趣的东西哦!今天“畅想资源”就来教大家如何使用CSS为内容设定特定的鼠标样 ...

  3. session过期后自动跳转到登陆页

    项目需要做一个自动登出的功能,查询了网上的资料,一开始准备用session监听做,按照下面方式配置监听器 1.在项目的web.xml文件中添加如下代码: <!--添加Session监听器--&g ...

  4. Chapter 8. Introduction to multi-project builds 多工程构建介绍

    Only the smallest of projects has a single build file and source tree, unless it happens to be a mas ...

  5. spring06Aop

    1.实现前置增强 必须实现接口MethodBeforeAdvice接口 创建对应的文件 public interface Animal {//主业务接口 void eat(); //目标方法 void ...

  6. repeater 结合checkbox批量删除

    项目中用到这个,从网上搜了搜相关内容,代码如下 <script type="text/javascript"> function checkAllThis(obj) { ...

  7. XML and JSON 验证

    function ChkJson(strJson) { //判断Json格式是否正确 if (strJson == null || strJson == "") return tr ...

  8. SQL2008 存储过程参数相关

      使用inputparame时,使用的是 varchar(20),和数据库中的DEPARTNAME完全匹配,可以查出值: USE [test] GO SET ANSI_NULLS OFF GO SE ...

  9. 安装VS2010后,如何设置老版本的项目文件不是默认用VS2010打开

    1.系统先后安装了VS2008和VS2010,在打开用VS2008创建的项目文件时总是会默认用VS2010打开,选择打开方式都不行,很不方便,差点要把VS2010卸载了.     其实只需要简单设置V ...

  10. vs2008下使用libcurl

    网上找了半天,总算找到一个比较好用的C++ 网络库,老实说,完全用Socket操作网络对于需要开发网络应用程序的人员来说还是很蛋疼很繁琐的.好在有这么一个给力的库.这个库的介绍可以自己百度一下,就我所 ...