题目链接: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. android 监听短信数据库,制作短信控制工具,控制别人的手机!!(一)

    序言:本程序示例本着简洁易懂的目的,只做了简单的功能实现,需要用户启动应用,收到短信才有效果.作者将会在后面的(二)篇中加入服务后台运行.自动启动功能,实现一个真正的短信控制工具.本文的目的很简单,让 ...

  2. 关于BT下载的一点事儿

    之前一直对BT下载很的好奇,今天迅雷出现了一些问题,于是上网了解了一下BT下载的原理,果然还是有所收获的. 1.为什么BT下载用户越多下载,速度越快? 答:BT全名为BitTorrent. 在传统下载 ...

  3. Linux驱动开发cdev驱动分层设计

    #ifndef MYDEV_H #define MYDEV_H #define DYNAMIC_MINOR 256 struct mydev{ const char *name; const stru ...

  4. 【网络流#3】hdu 1532 - Dinic模板题

    输入为m,n表示m条边,n个结点 记下来m行,每行三个数,x,y,c表示x到y的边流量最大为c 这道题的模板来自于网络 http://blog.csdn.net/sprintfwater/articl ...

  5. 一键cobbler批量安装脚本

    前几天机房上架180台服务器,太多了,使用了cobbler批量安装,具体的看我上代码,我把配置cobbler的命令给堆积起来,也算是个脚本吧,欢迎拍砖指正,下面我上脚本: #!/bin/bash # ...

  6. C# KTV 系统 SQL数据库连接 C# 应用窗体

    ---恢复内容开始--- 五道口 北大青鸟校区 KTV项目 指导老师: 袁玉明  SQL数据库关系图 第一步: private void DoubleClicklvContry() { ]!=null ...

  7. mysql_fetch_assoc() ,mysql_fetch_array() , mysql_fetch_row()的区别

    1. mysql_fetch_assoc() 函数从结果集中取得一行作为关联数组. 返回根据从结果集取得的行生成的关联数组,如果没有更多行,则返回 false. 输出: Array ( [LastNa ...

  8. JQuery 解析xml

    JQuery 可以通过 $.get() 或 $.post() 方法来加载 xml.     JQuery 解析 XML 与解析 DOM 一样, 可以使用 find(), children() 等函数来 ...

  9. JQuery 操作DOM

    DOM(Document Object Model—文档对象模型):一种与浏览器, 平台, 语言无关的接口, 使用该接口可以轻松地访问页面中所有的标准组件DOM 操作的分类:    DOM Core: ...

  10. CSS中常用中文字体转Unicode编码表

    中文名 英文名 Unicode Unicode 2 Mac OS 华文细黑 STHeiti Light [STXihei] \534E\6587\7EC6\9ED1 华文细黑 华文黑体 STHeiti ...