hdu4441 treap

#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[N], child[N][2], size[N], neg[N], val[N], pre[N];
char op[20];
ll sum[N];
int pos[N];
int stk[N],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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值