题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862
因为相同的值不能放在一起,所以我们加一个时间戳来标记相同的数的顺序。题目上说Score的范围是8位正整数,但我在06年的数据中发现了0,甚至还有10位正整数!坑了我好久。BZOJ上没有数据范围。。。我的结构体大小是一个个试出来的。。。代码比较渣。。。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int inf = 0x7fffffff - 1;
struct Node {
int val,id,sz;
Node *fa,*ch[2];
}*root,*null,Tr[400000+10],*node[400000+10];
struct Trie {
int ch[26];
bool value;
}T[400000+10];
int n,cnt,Tcnt,ticnt,ddcnt;
bool is;
int C[400000+10],fa[400000+10],ti[400000+10];
char s[1000+10];
Node* Newnode(Node *f,int val,int id) {
Tr[cnt].fa = f;Tr[cnt].val = val;Tr[cnt].id = id;Tr[cnt].sz = 0;Tr[cnt].ch[0] = Tr[cnt].ch[1] = null;return &Tr[cnt++];
}
void Update(Node *u) {
u -> sz = 1;
if(u -> ch[0] != null)u -> sz += u -> ch[0] -> sz;
if(u -> ch[1] != null)u -> sz += u -> ch[1] -> sz;
}
void Rotate(Node *u) {
Node *x = u -> fa,*y = x -> fa;int v = u == x -> ch[1];
u -> fa = y;if(y != null)y -> ch[x == y -> ch[1]] = u;
x -> ch[v] = u -> ch[v^1];if(u -> ch[v^1] != null)u -> ch[v^1] -> fa = x;
x -> fa = u;u -> ch[v^1] = x;Update(x);
}
void Splay(Node *u,Node *f) {
Node *x;
for(;(x = u -> fa) != f;Rotate(u))if(x -> fa != f)Rotate((u == x -> ch[1]) == (x == x -> fa -> ch[1]) ? x : u);
Update(u);if(f == null)root = u;
}
Node* Find_front(int x) {
Node *u = root,*ret;int rr = inf+1,tr = -2;
while(u != null) {
if(u -> val < x)u = u -> ch[0];
else {
if(u -> val < rr || (u -> val == rr && ti[u -> id] > tr)) {
rr = u -> val;ret = u;tr = ti[u -> id];
}
u = u -> ch[1];
}
}
return ret;
}
Node* Find_back(int x) {
Node *u = root,*ret;int rr = -2,tr = inf+1;
while(u != null) {
if(u -> val >= x)u = u -> ch[1];
else {
if(u -> val > rr || (u -> val == rr && ti[u -> id] < tr)) {
rr = u -> val;ret = u;tr = ti[u -> id];
}
u = u -> ch[0];
}
}
return ret;
}
Node* Find_front(int x,int t) {
Node *u = root,*ret;int rr = inf+1,tr = -2;
while(u != null) {
if(u -> val == x) {
if(ti[u -> id] >= t)u = u -> ch[0];
else {
if(rr != u -> val || ti[u -> id] > tr) {
rr = u -> val;
tr = ti[u -> id];
ret = u;
}
u = u -> ch[1];
}
}
else if(u -> val < x)u = u -> ch[0];
else {
if(u -> val < rr || (u -> val == rr && ti[u -> id] > tr)) {
rr = u -> val;ret = u;tr = ti[u -> id];
}
u = u -> ch[1];
}
}
return ret;
}
Node* Find_back(int x,int t) {
Node *u = root,*ret;int rr = -2,tr = inf+1;
while(u != null) {
if(u -> val == x) {
if(ti[u -> id] <= t)u = u -> ch[1];
else {
if(rr != u -> val || ti[u -> id] < tr) {
rr = u -> val;
tr = ti[u -> id];
ret = u;
}
u = u -> ch[0];
}
}
else if(u -> val > x)u = u -> ch[1];
else {
if(u -> val > rr || (u -> val == rr && ti[u -> id] < tr)) {
rr = u -> val;ret = u;tr = ti[u -> id];
}
u = u -> ch[0];
}
}
return ret;
}
void Insert(Node *u) {
Node *L = Find_front(u -> val),*R = Find_back(u -> val);
Splay(R,null);Splay(L,root);root -> ch[0] -> ch[1] = u;
u -> fa = root -> ch[0];Splay(u,null);
}
Node* Insert(int x,int id) {
Node *L = Find_front(x),*R = Find_back(x),*u;
Splay(R,null);Splay(L,root);u = root -> ch[0] -> ch[1] = Newnode(root -> ch[0],x,id);
Splay(u,null);return u;
}
void Delete(Node *u) {
Node *L = Find_front(u -> val,ti[u -> id]),*R = Find_back(u -> val,ti[u -> id]);
Splay(R,null);Splay(L,root);root -> ch[0] -> ch[1] = null;
Splay(root -> ch[0],null);
}
Node* Find(int x){
Node *u = root;
while(u != null) {
if(u -> ch[0] -> sz + 1 == x)return u;
if(x <= u -> ch[0] -> sz)u = u -> ch[0];
else {
x -= u -> ch[0]-> sz + 1;
u = u -> ch[1];
}
}
}
void init() {
null = Newnode(null,0,0);root = Newnode(null,inf,0);root -> ch[1] = Newnode(root,-1,0);Update(root -> ch[1]);Update(root);
}
int Insert() {
int l = strlen(s),now = 0;
for(int i = 1; i < l; i++) {
int id = s[i] - 'A',&ch = T[now].ch[id];
if(!ch)ch = ++Tcnt;
C[ch] = id;fa[ch] = now;now = ch;
}
if(T[now].value)is = true;
T[now].value = true;
return now;
}
void print(int u) {
if(u == 0)return;
print(fa[u]);
putchar(C[u]+'A');
}
void Dfs(Node *u) {
if(u == null)return;
Dfs(u -> ch[0]);
print(u -> id);ddcnt--;if(ddcnt)putchar(' ');
Dfs(u -> ch[1]);
}
int getnum() {
int ret = 0,l = strlen(s);
for(int i = 1; i < l; i++) {
ret = ret * 10 + s[i] - '0';
}
return ret;
}
int main() {
scanf("%d",&n);int x;init();
for(int i = 1; i <= n; i++) {
scanf("%s",s);
if(s[0] == '+') {
scanf("%d",&x);is = false;
int r = Insert();
if(is) {
Delete(node[r]);node[r] -> val = x;Insert(node[r]);
}
else {
node[r] = Insert(x,r);
}
ti[r] = ++ticnt;
}
else if(s[0] == '?') {
if(s[1] >= '0' && s[1] <= '9') {
int r = getnum(),ret = min(root -> sz,r+11);Node *L = Find(r),*R = Find(ret);
Splay(R,null);Splay(L,root);ddcnt = ret-r-1;
Dfs(root -> ch[0] -> ch[1]);
putchar('\n');
}
else {
int r = Insert();
Splay(node[r],null);
printf("%d\n",root -> ch[0] -> sz);
}
}
}
return 0;
}