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 ...
随机推荐
- ng-repeat 指令(带有数组)
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- deep learning学习记录一
最近不小心又赶了一下时髦,在做deep learning.今天去听了复旦吴老师的课程,感觉吴老讲解的还是很清晰的. 上午刚看过cnn,下午讲解的就是这章,相对来说,我听着给了很多启发.
- c语言描述的链队列的基本操作
#include<stdio.h> #include<stdlib.h> #define ok 0 #define error 1 //链队列特点在于不仅有链的头指针和尾指针, ...
- UICollectionViewCell「居左显示」
UICollectionViewCell「居左显示」 准备: 1.UICollectionView Left Aligned Layout 一款UICollectionView居左显示的约束点击下载_ ...
- iOS 崩溃日志分析(个人总结,最实用)
iOS 崩溃日志分析(个人总结,最实用) 要分析奔溃日志需要三个文件:crash日志,symbolicatecrash分析工具,.dSYM符号集 0. 在桌面创建一个crash文件夹 1. 需要Xco ...
- TortoiseSVN SendRpt.exe not found解决方案
重启了Explorer.exe即可.这里也补充下简单的重启Explorer.exe的方法:打开任务管理器,找到“Windows资源管理器”,右键--重新启动. 或者,右键--结束任务,然后点击 文件- ...
- C++继承和派生练习(一)--关于vehicle基类
Target:定义一个车(vehicle)基类 具有MaxSpeed.Weight等成员变量,Run.Stop等成员函数,由此派生出自行车(bicycle)类.汽车(motorcar)类. 自行车(b ...
- Python实现trim函数
Python中其实也有类似Java的trim函数的,叫做strip,举例: #!/usr/bin/python # -*- coding: UTF-8 -*- str = "0000000h ...
- Flask中对MySQL的基本操作
在Flask-SQLAlchemy中,插入.修改.删除操作,均由数据库会话管理. 会话用 db.session 表示.在准备把数据写入数据库前,要先将数据添加到会话中然后调用 commit() 方法提 ...
- Flask模拟实现CSRF攻击
CSRF CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造. CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求. 包括:以你名义发送邮件,发消息,盗取你的账号 ...