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 ...
随机推荐
- golang-Tag
Tag 理解 Golang中可以对struct定义Tag 例如: type TestTag struct{ UserName string `json:"name"` Age In ...
- Python 学习笔记(七)Python字符串(三)
常用字符串方法 split() 分割字符串,指定分隔符对字符串进行分割 join() 将序列中的元素以指定的字符连接生成一个新的字符串 str.strip() 用于移除字符串头尾指定的字符(默认 ...
- Question 20171117 Java中的编码问题?
撰文缘由 前几天做一个邮件发送功能,一些常用信息配置在properties文件中,通过prop.getProperty(key)来获取配置的信息,结果配置文件中是用中文写的,邮件发送成功后,邮箱中的激 ...
- Unity 游戏框架搭建 (八) 减少加班利器-QLog
为毛要实现这个工具? 在我小时候,每当游戏到了测试阶段,交给QA测试,QA测试了一会儿拿着设备过来说游戏闪退了....当我拿到设备后测了好久Bug也没有复现,排查了好久也没有头绪,就算接了Bugly拿 ...
- IPv4和IPv6的兼容问题
一网络拓扑 Ipv6网络1 路由器A IPv4网络 路由器B IPv6网络2 二知识补充 [注]双协议栈主机(路由器A.B)通过域名解析器区分传过来的是IPv4还是IPv6 三处理技术 双协议栈 Ip ...
- [Oracle]Audit(一)--认识Audit
1.Audit的概念 Audit是监视和记录用户对数据库进行的操作,以供DBA进行问题分析.利用Audit功能,可以完成以下任务: 监视和收集特定数据库活动的数据.例如管理员能够审计哪些表被更新,在某 ...
- selenium之Xpath定位
1. 绝对定位: driver.find_element_by_xpath("/html/body/div[x]/form/input") x 代表第x个 div标签,注意,索引从 ...
- iOS | 地图定位
在IOS开发中,最常见的功能之一就是地图定位功能,不单单是百度地图,高德地图等专业的地图导航软件,还有美团,咕咚等一些美食购物类和运动类也需要这样的功能,所以学会这项技能是一名IOS开发工程师必须的. ...
- 【mysql学习笔记整理】
/*mysql学习笔记整理*/ /*常用的数据库操作对象*/ #库的操作#创建#数据库的创建USE mysql;CREATE DATABASE db_x;#删除#删除数据库DROP DATABASE ...
- php 删除富文本编辑器保存内容中的其他代码(保留中文)
$str = '<p><p style="ve:"">测试筛选文本域内的中文 </p><p sty;"> ...