HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)
Now you are given a queue sequence and asked to perform several operations:
1. insert p
First you should find the smallest positive number (e.g. i) that does not appear in the current queue sequence, then you are asked to insert the +i at position p (position starts from 0). For -i, insert it into the right most position that result in a valid queue sequence (i.e. when encountered with element -x, the front of the queue should be exactly x).
For example, (+1 -1 +3 +4 -3 -4) would become (+1 +2 -1 +3 +4 -2 -3 -4) after operation 'insert 1'.
2. remove i
Remove +i and -i from the sequence.
For example, (+1 +2 -1 +3 +4 -2 -3 -4) would become (+1 +2 -1 +4 -2 -4) after operation 'remove 3'.
3. query i
Output the sum of elements between +i and -i. For example, the result of query 1, query 2, query 4 in sequence (+1 +2 -1 +4 -2 -4) is 2, 3(obtained by -1 + 4), -2 correspond.
In each case, the sequence is empty initially.
The input is terminated by EOF.
After each operation, output the sum of elements between +i and -i.
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long LL; const int MAXN = * ;
const int n = ;
int weight[MAXN], child[MAXN][], size[MAXN], neg[MAXN], val[MAXN], pre[MAXN];
LL sum[MAXN];
int pos[MAXN];
int stk[MAXN], top, node_cnt; int m, p, x, root;
char s[]; priority_queue<int> Q;
int int_cnt; void test(int x) {
if(child[x][]) test(child[x][]);
cout<<val[x]<<" "<<sum[x]<<" "<<x<<" "<<pre[x]<<" "<<(child[pre[x]][] == x)<<endl;
//cout<<val[x]<<endl;
if(child[x][]) test(child[x][]);
} void init() {
while(!Q.empty()) Q.pop();
int_cnt = top = node_cnt = ;
} int new_int() {
if(!Q.empty()) {
int ret = -Q.top(); Q.pop();
return ret;
}
return ++int_cnt;
} int new_node(int f, int v) {
int x = (top ? stk[top--] : ++node_cnt);
pre[x] = f;
sum[x] = val[x] = v;
if(v < ) pos[n - v] = x;
else pos[v] = x;
size[x] = ; neg[x] = (v < );
weight[x] = rand();
child[x][] = child[x][] = ;
return x;
} void update(int x) {
sum[x] = sum[child[x][]] + sum[child[x][]] + val[x];
size[x] = size[child[x][]] + size[child[x][]] + ;
neg[x] = neg[child[x][]] + neg[child[x][]] + (val[x] < );
} void rotate(int &x, int t) {
int y = child[x][t];
child[x][t] = child[y][t ^ ];
child[y][t ^ ] = x;
pre[y] = pre[x]; pre[x] = y;
pre[child[x][t]] = x;
update(x); update(y);
x = y;
} void insert1(int f, int &x, int k, int v) {
if(x == ) x = new_node(f, v);
else {
int t = (size[child[x][]] + <= k);
insert1(x, child[x][t], k - t * (size[child[x][]] + ), v);
if(weight[child[x][t]] < weight[x]) rotate(x, t);
}
update(x);
} int cnt_pos(int x, int t) {
if(!x) return ;
int ret = cnt_pos(pre[x], child[pre[x]][] == x);
if(t == ) ret += size[child[x][]] - neg[child[x][]] + (val[x] > );
return ret;
} void insert2(int f, int &x, int k, int v) {
if(x == ) x = new_node(f, v);
else {
int t = (neg[child[x][]] + (val[x] < ) <= k);
insert2(x, child[x][t], k - t * (neg[child[x][]] + (val[x] < )), v);
if(weight[child[x][t]] < weight[x]) rotate(x, t);
}
update(x);
} void remove(int &x) {
if(child[x][] && child[x][]) {
int t = weight[child[x][]] < weight[child[x][]];
rotate(x, t);
remove(child[x][t ^ ]);
} else {
stk[++top] = x;
pre[child[x][]] = pre[child[x][]] = pre[x];
x = child[x][] + child[x][];
}
if(x > ) update(x);
} LL query1(int x, int t) {
if(!x) return ;
LL ret = query1(pre[x], child[pre[x]][] == x);
if(t == ) ret += sum[child[x][]] + val[x];
return ret;
} LL query2(int x, int t) {
if(!x) return ;
LL ret = query2(pre[x], child[pre[x]][] == x);
if(t == ) ret += sum[child[x][]] + val[x];
return ret;
} LL query(int x, int a, int b) {
LL ret = query1(pre[a], child[pre[a]][] == a) + sum[child[a][]];
ret += query2(pre[b], child[pre[b]][] == b) + sum[child[b][]];
return ret;
} void update_parent(int t) {
while(t) update(t), t = pre[t];
} int main() {
for(int t = ; ; ++t) {
if(scanf("%d", &m) == EOF) break;
init();
printf("Case #%d:\n", t);
root = ;
while(m--) {
scanf("%s%d", s, &x);
if(*s == 'i') {
int tmp = new_int();
insert1(, root, x, tmp);
int k = cnt_pos(pos[tmp], ) - ;
insert2(, root, k, -tmp);
}
if(*s == 'r') {
if(root == pos[x]) {
remove(root);
}
else {
int t = pos[x], p = pre[t];
remove(child[p][child[p][] == t]);
update_parent(p);
}
int y = x + n;
if(root == pos[y]) {
remove(root);
}
else {
int t = pos[y], p = pre[t];
remove(child[p][child[p][] == t]);
update_parent(p);
}
Q.push(-x);
}
if(*s == 'q') {
printf("%I64d\n", query(root, pos[x], pos[x + n]));
}
//test(root);
}
}
}
HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)的更多相关文章
- HDU 4433 locker(DP)(2012 Asia Tianjin Regional Contest)
Problem Description A password locker with N digits, each digit can be rotated to 0-9 circularly.You ...
- HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )
Sum of divisors Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)
Problem Description In this problem, you are given several strings that contain only digits from '0' ...
- HDU 4433 locker 2012 Asia Tianjin Regional Contest 减少国家DP
意甲冠军:给定的长度可达1000数的顺序,图像password像锁.可以上下滑动,同时会0-9周期. 每个操作.最多三个数字连续操作.现在给出的起始序列和靶序列,获得操作的最小数量,从起始序列与靶序列 ...
- HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)
Problem Description Japanese Mahjong is a four-player game. The game needs four people to sit around ...
- 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 4441 Queue Sequence
http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:对于一个序列,每次有三种操作 insert pos 表示在pos插入一个数,这个数是最小的正数 ...
- HDU 4441 Queue Sequence(splay)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并 ...
- HDU 4468 Spy(KMP+贪心)(2012 Asia Chengdu Regional Contest)
Description “Be subtle! Be subtle! And use your spies for every kind of business. ”― Sun Tzu“A spy w ...
随机推荐
- JavaScript:直接写入 HTML 输出流
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Oracle 11g行字段拼接WMSYS.WM_CONCAT问题Not A LOB
Oracle 11g行字段拼接WMSYS.WM_CONCAT问题Not A LOB 一.问题出现 项目中的某个查询需要将表中某个字段不重复地拼接起来,百度得到该函数WMSYS.WM_CONCAT(字段 ...
- JavaScript 表单处理
表单对象的属性 name action method encoding target elements 表单对象的方法 submit reset 表单元素事件 文本域事件:onFocus(获得焦点) ...
- WebGL学习笔记(2)
根据上一篇学习笔记,理解WebGL的工作原理及基本调用代码后,可以开始研究3D顶点对象的缩放.旋转.以及对对象进行可交互(鼠标或键盘控制)的旋转或者缩放. 要理解对象的旋转/缩放需要首先学习矩阵的计算 ...
- Failed to introspect bean class [org.springframework.orm.hibernate5.LocalSessionFactoryBean] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClass
依赖引入 错误可能版本 不对 Failed to introspect bean class [org.springframework.orm.hibernate5.LocalSessionFact ...
- spring boot 搭建基本套路《1》
1. Spring复习 Spring主要是创建对象和管理对象的框架. Spring通过DI实现了IoC. Spring能很大程度的实现解耦. 需要掌握SET方式注入属性的值. 需要理解自动装配. 需要 ...
- collections模块的使用
1. Counter counter是collections中的一个模块, 它能够统计出字符串/文本中的每一个元素出现的次数, 并可以对结果进行进一步的处理. 使用方法 传入: 字符串 默认返回: C ...
- 一次 group by + order by 性能优化分析
一次 group by + order by 性能优化分析 最近通过一个日志表做排行的时候发现特别卡,最后问题得到了解决,梳理一些索引和MySQL执行过程的经验,但是最后还是有5个谜题没解开,希望大家 ...
- CentOS 同步时间的方法
与时间服务器上的时间同步的方法 1. 安装ntpdate工具 # yum -y install ntp ntpdate 2. 设置系统时间与网络时间同步 # ntpdate cn.pool.ntp ...
- tarnado源码解析系列一
目录 tarnado tarnado源码安装 tarnado测试程序 application类的解析 一. tarnado简介 最近在学习Python,无意间接触到的tarnado,感觉tarnado ...