您的位置:首页 > 其它

hdu4441 treap

2014-05-05 19:05 441 查看
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <set>
#include <stack>

using namespace std;
#define ll long long
#define eps 1e-10
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sqr(x) ((x)*(x))
#define lson (u<<1)
#define rson (u<<1|1)
const int n = 100000;
const int N = 200020;

int m,p,root,x;
int weight
, child
[2], size
, neg
, val
, pre
;
char op[20];
ll sum
;
int pos
;
int stk
,top,node_cnt;
priority_queue<int> pq;
int int_cnt;
void init() {
while(!pq.empty()) pq.pop();
int_cnt = top = node_cnt = 0;
}

int new_int() {
if(!pq.empty()) {
int ret = -pq.top(); pq.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 < 0) pos[n - v] = x;
else pos[v] = x;
size[x] = 1; neg[x] = (v < 0);
weight[x] = rand();
child[x][0] = child[x][1] = 0;
return x;
}

void update(int x) {
sum[x] = sum[child[x][0]] + sum[child[x][1]] + val[x];
size[x] = size[child[x][0]] + size[child[x][1]] + 1;
neg[x] = neg[child[x][0]] + neg[child[x][1]] + (val[x] < 0);
}

void rotate(int &x, int t) {
int y = child[x][t];
child[x][t] = child[y][t ^ 1];
child[y][t ^ 1] = 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 == 0) x = new_node(f, v);
else {
int t = (size[child[x][0]] + 1 <= k);
insert1(x, child[x][t], k - t * (size[child[x][0]] + 1), v);
if(weight[child[x][t]] < weight[x]) rotate(x, t);
}
update(x);
}

int cnt_pos(int x, int t) {
if(!x) return 0;
int ret = cnt_pos(pre[x], child[pre[x]][1] == x);
if(t == 1) ret += size[child[x][0]] - neg[child[x][0]] + (val[x] > 0);
return ret;
}

void insert2(int f, int &x, int k, int v) {
if(x == 0) x = new_node(f, v);
else {
int t = (neg[child[x][0]] + (val[x] < 0) <= k);
insert2(x, child[x][t], k - t * (neg[child[x][0]] + (val[x] < 0)), v);
if(weight[child[x][t]] < weight[x]) rotate(x, t);
}
update(x);
}

void remove(int &x) {
if(child[x][0] && child[x][1]) {
int t = weight[child[x][0]] < weight[child[x][1]];
rotate(x, t);
remove(child[x][t ^ 1]);
} else {
stk[++top] = x;
pre[child[x][0]] = pre[child[x][1]] = pre[x];
x = child[x][0] + child[x][1];
}
if(x > 0) update(x);
}

ll query1(int x, int t) {
if(!x) return 0;
ll ret = query1(pre[x], child[pre[x]][1] == x);
if(t == 0) ret += sum[child[x][1]] + val[x];
return ret;
}

ll query2(int x, int t) {
if(!x) return 0;
ll ret = query2(pre[x], child[pre[x]][1] == x);
if(t == 1) ret += sum[child[x][0]] + val[x];
return ret;
}

ll query(int x, int a, int b) {
ll ret = query1(pre[a], child[pre[a]][1] == a) + sum[child[a][1]];
ret += query2(pre[b], child[pre[b]][1] == b) + sum[child[b][0]];
return ret;
}

void update_parent(int t) {
while(t) update(t), t = pre[t];
}
int main()
{

int cs = 0;
while(scanf("%d",&m)!=EOF)
{
init();
root = 0;
printf("Case #%d:\n", ++cs);
while(m--)
{
scanf("%s%d",op,&x);
if(op[0]=='i'){
int tmp = new_int();
insert1(0,root,x,tmp);
int k = cnt_pos(pos[tmp],1) - 1;
insert2(0,root,k,-tmp);
}
else if(op[0]=='r'){
if(root==pos[x]) remove(root);
else{
int t = pos[x], p = pre[t];
remove(child[p][child[p][1]==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][1]==t]);
update_parent(p);
}
pq.push(-x);
}
else{
printf("%I64d\n",query(root,pos[x],pos[x+n]));
}
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: