HDU3726---Graph and Queries 离线处理+Treap
题目链接: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的更多相关文章
- [HDU3726]Graph and Queries
Problem 给你一张图,点的权值,边和几个操作: D x: 删除第x条边 Q x y: 询问包含x的联通块中权值第y大的权值 C x y: 将x这个点的权值改为y Solution 一看就要离线处 ...
- uvalive 5031 Graph and Queries 名次树+Treap
题意:给你个点m条边的无向图,每个节点都有一个整数权值.你的任务是执行一系列操作.操作分为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 ...
- 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 ...
- [la P5031&hdu P3726] Graph and Queries
[la P5031&hdu P3726] Graph and Queries Time Limit: 10000/5000 MS (Java/Others) Memory Limit: ...
- UVaLive 5031 Graph and Queries (Treap)
题意:初始时给出一个图,每个点有一个权值,三种操作:(1)删除某个边:(2)修改每个点的权值:(3)询问与节点x在一个连通分量中所有点的第K大的权值. 析:首先是要先离线,然后再倒着做,第一个操作就成 ...
- UVALive 5031 Graph and Queries (Treap)
删除边的操作不容易实现,那么就先离线然后逆序来做. 逆序就变成了合并,用并存集判断连通,用Treap树来维护一个连通分量里的名次. Treap = Tree + Heap.用一个随机的优先级来平衡搜索 ...
- UVALive5031 Graph and Queries(Treap)
反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...
随机推荐
- Java中equals和“==””的区别,String特殊
public class TestString { /* * java中的数据类型,可分为两类: * 1.基本数据类型,也称为原始数据类型.byte,short,char,int,long,float ...
- select 响应时间 js
HTML form select表单标签案例代码如下: 跳转菜单的需要放在head头部标签内的JS脚本代码:<script type="text/javascript"> ...
- C语言二叉树的建立与遍历
二叉树的建立和遍历都要用到递归,先暂时保存一下代码,其中主要是理解递归的思想,其它的就都好理解了.这里是三种遍历方式,其实理解一种,其它的几个就都理解了,就是打印出来的顺序不一样而已.建立和遍历的方式 ...
- C#中MD5加密
C#中进行MD5加密需要使用MD5这个类,这个类位于System.Security.Cryptography命名空间. 转到元数据得知MD5是抽象类和两个静态方法 上代码详解: //得到其静态方法创建 ...
- C# 面向对象 , 抽象基类
抽象基类 关键字, abstract abstract class SSS { public void aaa() { } } 作为抽象基类, 只能在 继承关系 中 担任父类的角色,不能出现在其他地 ...
- Socket服务端口长连接最多能支持多少?
答案是无限的.视服务端的资源而不同. 以前一直认为服务端在Accept客户端连接后,会开启一个新的端口与客户端建立链路,但这是错误的.事实上,一个连路是由Server IP+server Port + ...
- nyoj 44
//nyoj 44 //和上面一题一样,求子串和,但是代码非常简洁..... 时间复杂度为n #include <iostream> using namespace std; int ma ...
- jquery插件--多行文本缩略
1.webkit内核多行缩略样式 text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orie ...
- Delphi 做ActiveX的详细过程
1.新建 如下图 点击OK 依然点击OK 出现了如上图的节面,就像窗体一样. 然后 你就想干什么干什么. 这个做好之后, 这个是我设计的窗体. 然后 就添加 外部可以调用的接口了. 如果你不想让外部调 ...
- Php ORM 对象关系映射
ORM的全称是Object Relational Mapping,即对象关系映射.它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将 ...