HDU 3726 Graph and Queries treap树
题目来源:HDU 3726 Graph and Queries
题意:见白书
思路:刚学treap 參考白皮书
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std; struct Node
{
Node *ch[2];
int r;
int v;
int s;
Node(int v): v(v) {
ch[0] = ch[1] = NULL; r = rand(); s = 1;
}
bool operator < (const Node& rhs) const{
return r < rhs.r;
}
int cmp(int x) const{
if(x == v) return -1;
return x < v ? 0 : 1;
}
void maintain(){
s = 1;
if(ch[0] != NULL) s += ch[0]->s;
if(ch[1] != NULL) s += ch[1]->s;
}
}; void rotate(Node* &o, int d){
Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
o->maintain(); k->maintain(); o = k;
} void insert(Node* &o, int x){
if(o == NULL){
o = new Node(x);
}
else{
int d = (x < o->v ? 0 : 1);
insert(o->ch[d], x);
if(o->ch[d] > o) rotate(o, d^1);
}
o->maintain();
//printf("--------+%d\n", o->s);
} void remove(Node* &o, int x){
int d = o->cmp(x);
if(d == -1){
Node* u = o;
if(o->ch[0] != NULL && o->ch[1] != NULL){
int d2 = o->ch[0] > o->ch[1] ? 1 : 0;
rotate(o, d2); remove(o->ch[d2], x);
}
else{
if(o->ch[0] == NULL) o = o->ch[1];
else o = o->ch[0];
delete u;
}
}
else
remove(o->ch[d], x);
if(o != NULL) o->maintain();
} const int maxn = 20010;
const int maxc = 500010;
int n, m, w[maxn], from[maxn*3], to[maxn*3], removed[maxn*3];
int f[maxn]; Node* root[maxn]; struct Command
{
char type;
int x, p;
Command(){}
Command(char type, int x, int p): type(type), x(x), p(p) { }
}commands[maxc]; int find(int x)
{
if(x != f[x])
return f[x] = find(f[x]);
return f[x];
}
int kth(Node* o, int k){
if(o == NULL || k <= 0 || k > o->s)
return 0;
int s = (o->ch[1] == NULL ? 0 : o->ch[1]->s);
if(k == s+1) return o->v;
else if(k <= s) return kth(o->ch[1], k);
else return kth(o->ch[0], k-s-1);
} void mergeto(Node* &src, Node* &dest){ if(src->ch[0] != NULL) mergeto(src->ch[0], dest);
if(src->ch[1] != NULL) mergeto(src->ch[1], dest);
insert(dest, src->v);
delete src;
src = NULL;
} void add_edge(int x){
int u = find(from[x]), v = find(to[x]);
//printf("-/++++%d %d\n", u, v);
if(u != v){
if(root[u]->s > root[v]->s){
f[v] = u;
//printf("----%d %d\n", root[v]->s, root[u]->s);
mergeto(root[v], root[u]);
//printf("----%d\n", root[u]->s);
}
else{
f[u] = v;
//printf("----%d %d\n", root[u]->s, root[v]->s);
mergeto(root[u], root[v]);
//printf("++++%d\n", root[v]->s);
}
}
} void removetree(Node* &x){
if(x->ch[0] != NULL) removetree(x->ch[0]);
if(x->ch[1] != NULL) removetree(x->ch[1]);
delete x;
x = NULL;
} int query_cnt;
long long query_tol; void query(int x, int k){
query_cnt++;
//printf("%d %d\n", root[find(x)]->s, kth(root[find(x)], k));
query_tol += kth(root[find(x)], k);
} void change_weight(int x, int v){
int u = find(x);
remove(root[u], w[x]);
insert(root[u], v);
w[x] = v;
}
int main()
{
int kase = 0;
while(scanf("%d %d", &n, &m) && (n||m))
{
for(int i = 1; i <= n; i++)
scanf("%d", &w[i]);
for(int i = 1; i <= m; i++)
scanf("%d %d", &from[i], &to[i]);
memset(removed, 0, sizeof(removed));
int c = 0;
while(1)
{
char type[2];
int x, p = 0, v = 0;
scanf("%s", type);
if(type[0] == 'E')
break;
scanf("%d", &x);
if(type[0] == 'D')
removed[x] = 1;
if(type[0] == 'Q')
scanf("%d", &p);
if(type[0] == 'C')
{
scanf("%d", &v);
p = w[x];
w[x] = v;
}
commands[c++] = Command(type[0], x, p);
} for(int i = 1; i <= n; i++)
{
f[i] = i;
if(root[i] != NULL)
removetree(root[i]);
root[i] = new Node(w[i]);
//printf("******%d\n", root[i]->s);
}
for(int i = 1; i <= m; i++)
if(!removed[i])
{
add_edge(i);
//puts("gh");
}
query_tol = query_cnt = 0;
for(int i = c-1; i >= 0; i--){
if(commands[i].type == 'D')
add_edge(commands[i].x);
if(commands[i].type == 'Q')
query(commands[i].x, commands[i].p);
if(commands[i].type == 'C')
change_weight(commands[i].x, commands[i].p);
}
printf("Case %d: %.6lf\n", ++kase, query_tol/(double)query_cnt);
}
return 0;
}
HDU 3726 Graph and Queries treap树的更多相关文章
- 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 ...
- HDU 3726 Graph and Queries (离线处理+splay tree)
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
题意:给你个点m条边的无向图,每个节点都有一个整数权值.你的任务是执行一系列操作.操作分为3种... 思路:本题一点要逆向来做,正向每次如果删边,复杂度太高.逆向到一定顺序的时候添加一条边更容易.详见 ...
- LA 5031 Graph and Queries —— Treap名次树
离线做法,逆序执行操作,那么原本的删除边的操作变为加入边的操作,用名次树维护每一个连通分量的名次,加边操作即是连通分量合并操作,每次将结点数小的子树向结点数大的子树合并,那么单次合并复杂度O(n1lo ...
- UVALive5031 Graph and Queries(Treap)
反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...
- 【HDOJ】3726 Graph and Queries
Treap的基础题目,Treap是个挺不错的数据结构. /* */ #include <iostream> #include <string> #include <map ...
- UVaLive 5031 Graph and Queries (Treap)
题意:初始时给出一个图,每个点有一个权值,三种操作:(1)删除某个边:(2)修改每个点的权值:(3)询问与节点x在一个连通分量中所有点的第K大的权值. 析:首先是要先离线,然后再倒着做,第一个操作就成 ...
随机推荐
- 弹出框美化 alert样式美化
引用style.css和ui.js就可以直接用以下接口调用!(文末附完整代码) alert_带标题: mizhu.alert('alert_带标题', '这是alert效果'); alert_带图标: ...
- HDU 5114 扩展欧几里得
题目大意:给你两个球的坐标 他们都往(1, 1)这个方向以相同的速度走,问你他们在哪个位置碰撞. 思路:这种题目需要把x方向和y方向分开来算周期,两个不同周期需要用扩展欧几里得来求第一次相遇. #in ...
- 四十二 常用内建模块 collections
collections是Python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: >>> ...
- 计划任务at cron
计划任务作用:做一些周期性的任务,主要用于定时备份数据,同步时间,定时删除日志 所有计划任务执行的输出都会以邮件的方式发送给指定用户,除非重定向 (1)at:一次性调度执行 1)安装 yum inst ...
- react native android 应用状态(前端或后台)的判断
当Android应用程序被暂时放到了后台,或者又重新回到前台,是否有相应的事件可以处理到? 例如,当你的应用暂时放到了后台,是否应该做出一些操作,暂时保存界面上的数据? 可以参考:https://gi ...
- 如何用jmeter对websockt和protobuf进行压力测试
参考代码:https://github.com/hutao722/kekexinxin 这是基于Jmeter WebsocketSampler的插件,支持对基于websocket和protobuf的服 ...
- 29、Flask实战第29天:cms用户名渲染和注销功能实现
这节来完成用户名渲染和注销的功能,目前用户名在前端页面是写死的,我们需要动态的展示出来 用户名渲染 实现用户名动态展示,其中一种方法就是在视图函数,根据session信息,获取到user id,通过该 ...
- angularjs学习笔记3-directive中scope的绑定修饰符
在angularjs中,一个directive返回一个对象,对象存在很多属性,并且可以在directive中自定义自己的scope,而使用自己的scope是为了防止一个directive被使用在多个地 ...
- START法则
用途:在做项目总结以及阶段性报告等的时候,可以很好的帮自己对整个工作过程进行梳理和总结,很好的表现出自己分析问题的清晰性.条理性和逻辑性. 定义:STAR法则是情境(situation).任务(tas ...
- 初见Python<5>:条件、循环和其他语句
1.使用逗号输出 使用逗号隔开,可以打印多个表达式.打印后,各项之间自动以一个空格隔开. 也可以同时输出文本和变量值. 可以和字符串连接符“+”一起使用. 2.从模块中导入函数 从模块导入函数的方 ...