insert p 在p后面插入一个没有出现过的最小的正整数。
remove i 把+i和-i从数列里面弄出去。
query i 询问+i到-i的区间和。
最小的没有出现过的正整数可以用set或者线段树什么的保存。用g[i][2]保存 i在splay里的结点编号。数组要开够20w。
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#pragma comment(linxer, "/STACK:102400000,102400000")
#define LL long long
#define pii pair<int, int>
#define MP maxe_pair
//#define ls i << 1
//#define rs ls | 1
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 200020
#define M 500010
struct Splay{
int pre[N], val[N], ch[N][2], pos[N], nag[N], sz[N];
int tot, root;
LL sum[N];
int creat(int v, int fa){
int x = ++tot;
pre[x] = fa;
val[x] = v;
sum[x] = v;
ch[x][0] = ch[x][1] = 0;
sz[x] = 1;
pos[x] = v > 0;
nag[x] = v < 0;
return x;
}
void push_up(int x){
int ls = ch[x][0], rs = ch[x][1];
sz[x] = sz[ls] + sz[rs] + 1;
sum[x] = sum[ls] + sum[rs] + val[x];
pos[x] = pos[ls] + pos[rs] + (val[x] > 0);
nag[x] = nag[ls] + nag[rs] + (val[x] < 0);
}
void push_down(int x){
}
void init(){
tot = 0;
root = creat(0, 0);
ch[root][1] = creat(0, root);
push_up(root);
}
void P(int x){
if(pre[x])
P(pre[x]);
push_down(x);
}
void rotate(int x){
int y = pre[x], d = ch[y][1] == x;
ch[y][d] = ch[x][!d];
if(ch[x][!d]) pre[ch[x][!d]] = y;
ch[x][!d] = y;
pre[x] = pre[y];
pre[y] = x;
if(pre[x]) ch[pre[x]][ch[pre[x]][1] == y] = x;
push_up(y);
}
void splay(int x, int goal){
//P(x);
while(pre[x] != goal){
int f = pre[x], ff = pre[f];
if(ff == goal)
rotate(x);
else if((ch[ff][1] == f) == (ch[f][1] == x))
rotate(f), rotate(x);
else
rotate(x), rotate(x);
}
push_up(x);
if(goal == 0) root = x;
}
int kth(int k){
int x = root;
while(x){
//push_down(x);
if(sz[ch[x][0]] >= k) x = ch[x][0];
else{
k -= sz[ch[x][0]] + 1;
if(k == 0)
return x;
x = ch[x][1];
}
}
return x;
}
int find(int x, int m){
int ls = ch[x][0], rs = ch[x][1];
if(nag[ls] == m && val[x] < 0){
splay(x, 0);
return sz[ch[root][0]];
}
else if(nag[ls] >= m + 1)
return find(ls, m);
else
return find(rs, m - nag[ls] - (val[x] < 0));
}
int insert(int k, int v){
splay(kth(k), 0);
splay(kth(k + 1), root);
int f = ch[root][1];
ch[f][0] = creat(v, f);
push_up(f);
push_up(root);
return ch[f][0];
}
void delet(int x){
splay(x, 0);
int k = sz[ch[root][0]];
splay(kth(k), 0);
splay(kth(k + 2), root);
int f = ch[root][1];
ch[f][0] = 0;
push_up(f);
push_up(root);
}
void output(int x){
if(!x) return ;
output(ch[x][0]);
printf("%d ", val[x]);
output(ch[x][1]);
}
}S;
int g[N][2], n;
set<int> ss;
void Insert(int p){
int v = *(ss.begin());
ss.erase(v);
g[v][0] = S.insert(p + 1, v);
S.splay(g[v][0], 0);
int plus = S.pos[S.ch[S.root][0]];
if(S.nag[S.root] <= plus){
int m = S.sz[S.root] - 1;
g[v][1] = S.insert(m, -v);
}
else{
int m = S.find(S.root, plus);
g[v][1] = S.insert(m, -v);
}
}
void Query(int v){
int x = g[v][0], y = g[v][1];
S.splay(x, 0);
S.splay(y, S.root);
int p = S.ch[S.ch[S.root][1]][0];
printf("%lld\n", S.sum[p]);
}
void Remove(int v){
int x = g[v][0], y = g[v][1];
S.delet(x);
S.delet(y);
ss.insert(v);
}
int main(){
int cas = 0;
while(scanf("%d", &n) != EOF){
ss.clear();
for(int i = 1; i <= n; ++i)
ss.insert(i);
S.init();
printf("Case #%d:\n", ++cas);
char s[20];
int v;
while(n--){
scanf("%s%d", s, &v);
if(s[0] == 'i')
Insert(v);
else if(s[0] == 'q')
Query(v);
else Remove(v);
//S.output(S.root); puts("");
}
}
return 0;
}