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; }
相关文章推荐
- 阿里雲服務器
- 深入探讨 Java 类加载器
- 可控硅过零导通程序--可控硅驱动程序
- POJ 1018 Communication System(枚举)
- MySQL-Front的安装简介
- C++继承类和基类之间成员函数和虚函数调用机制
- MRC和ARC混编
- xcode
- HDU 2845 Beans
- AirPlay
- Android学习笔记_72_Spinner的用法
- Maven 执行Javadoc时控制台输出乱码问题
- 京东云擎(JAE)免费搭建WordPress站点
- 21访问系统注册表
- Linked List Cycle
- Android 电话系统框架介绍
- MySQL-Front的安装简介
- 元首的愤怒 SharePoint Apps
- 自定义水平进度条
- 外观模式(门面模式)