一开始以为是一道搜索树的模板题,但是一看数据量10^8不能直接暴力搞了,之后就写了一篇巨长的代码,想了一下把top出的节点建树可以解决, 一开始想复杂了,导致我写了splay,SBT,hash,敲完代码手指头都有点抽了(o(╯□╰)o),后来看别人的题解发现都是离散化+离线解决的,而且只用splay就可以了,但是已经敲了这么长的代码,不忍心放弃,只好硬着头皮在线搞,还好都解决了,最后在求rank的时候遇到了一点障碍,如果有Rank i , i <= size, size为top出的不同数字个数,的时候可以直接在splay中找到排名为i的节点并把splay到树根,输出其中的记录的数字即可,然而i > size时,并不是很好搞,因为人的编号为1, 2, ..., n ,所以当没有top的时候直接输出i即可,如果有top的时候,就要判断一下大于等于i的数字有多少被top到前面去了,用i减去这些数的个数,然后还要判断一下top的数字中大于等于现在的i小于上一个i 的数字个数,然后再减去,以此循环直到数字个数为0,仅一次rank操作的最坏的复杂度是O(n*logn),后来在sbt里谢了个回溯fun函数可以解决这个问题,最后还不错1A了
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;
const int MAXN(100010);
const int MOD(1313131);
template<typename T>
struct SBT
{
struct NODE
{
T key;
int size;
NODE *left, *right;
};
NODE pool[MAXN];
NODE *root, *NIL, *rear;
T tkey;
void init()
{
NIL = pool;
NIL->left = NIL->right = NIL;
NIL->size = 0;
rear = pool+1;
root = NIL;
}
void newnode(NODE *&sour, const T &value)
{
rear->key = value;
rear->size = 1;
rear->left = rear->right = NIL;
sour = rear++;
}
void left_rotate(NODE *&sour)
{
NODE *temp = sour->right;
sour->right = temp->left;
temp->left = sour;
temp->size = sour->size;
sour->size = sour->left->size+sour->right->size+1;
sour = temp;
}
void right_rotate(NODE *&sour)
{
NODE *temp = sour->left;
sour->left = temp->right;
temp->right = sour;
temp->size = sour->size;
sour->size = sour->left->size+sour->right->size+1;
sour = temp;
}
void maintain(NODE *&sour, bool flag)
{
if(flag == false)
{
if(sour->left->left->size > sour->right->size)
right_rotate(sour);
else
if(sour->left->right->size > sour->right->size)
{
left_rotate(sour->left);
right_rotate(sour);
}
else
return;
}
else
{
if(sour->right->right->size > sour->left->size)
left_rotate(sour);
else
if(sour->right->left->size > sour->left->size)
{
right_rotate(sour->right);
left_rotate(sour);
}
else
return;
}
maintain(sour->right, true);
maintain(sour->left, false);
maintain(sour, true);
maintain(sour, false);
}
void insert(const T &value)
{
tkey = value;
insert_(root);
}
void insert_(NODE *&sour)
{
if(sour == NIL)
{
newnode(sour, tkey);
return;
}
++sour->size;
if(tkey < sour->key)
insert_(sour->left);
else
insert_(sour->right);
maintain(sour, tkey >= sour->key);
}
NODE *search(const T &value)
{
NODE *sour = root;
while(root != NIL && sour->key != value)
{
if(value < sour->key)
sour = sour->left;
else
sour = sour->right;
}
return sour;
}
int rank(const T &value)
{
NODE *sour = root;
int ret = 1;
while(sour != NIL)
{
if(value <= sour->key)
sour = sour->left;
else
{
ret += sour->left->size+1;
sour = sour->right;
}
}
return ret;
}
NODE *successor(const T& value)
{
tkey = value;
return successor(root);
}
NODE *successor_(NODE *sour)
{
if(sour == NIL)
return NIL;
if(tkey < sour->key)
{
NODE *temp = successor_(sour->left);
if(temp == NIL)
return sour;
else
return temp;
}
else
{
return successor_(sour->right);
}
}
int tv;
int ret;
int fun(int value)
{
tv = value;
fun_(root);
return tv;
}
void fun_(NODE *sour)
{
if(sour == NIL)
return;
if(tv <= sour->key.num)
{
tv -= sour->right->size+1;
fun_(sour->left);
}
else
{
fun_(sour->right);
if(tv <= sour->key.num)
{
tv -= 1;
fun_(sour->left);
}
}
}
};
struct SPLAY_TREE
{
struct NODE
{
int num;
int size;
NODE *fa;
NODE *ch[2];
};
NODE pool[MAXN];
NODE *root, *NIL, *rear;
NODE *ll, *rl;
inline void push_up(NODE *sour)
{
sour->size = sour->ch[0]->size+sour->ch[1]->size+1;
}
void init()
{
NIL = pool;
NIL->fa = NIL->ch[0] = NIL->ch[1] = NIL;
NIL->size = 0;
rear = pool+1;
newnode(root, NIL, -1);
newnode(root->ch[1], root, -1);
ll = root;
rl = root->ch[1];
push_up(rl);
push_up(ll);
}
void newnode(NODE *&sour, NODE *f, int tn)
{
rear->num = tn;
rear->fa = f;
rear->ch[0] = rear->ch[1] = NIL;
rear->size = 1;
sour = rear++;
}
void rotate(NODE *sour, int flag)
{
NODE *f = sour->fa;
f->ch[!flag] = sour->ch[flag];
sour->ch[flag]->fa = f;
sour->fa = f->fa;
if(f->fa != NIL)
f->fa->ch[f->fa->ch[1] == f] = sour;
sour->ch[flag] = f;
f->fa = sour;
push_up(f);
}
void splay(NODE *sour, NODE *goal)
{
while(sour->fa != goal)
{
if(sour->fa->fa == goal)
rotate(sour, sour->fa->ch[0] == sour);
else
{
NODE *f = sour->fa;
int flag = (f->fa->ch[0] == f);
if(f->ch[flag] == sour)
rotate(sour, !flag);
else
rotate(f, flag);
rotate(sour, flag);
}
}
push_up(sour);
if(goal == NIL)
root = sour;
}
NODE *extreme(NODE *sour, int flag)
{
while(sour->ch[flag] != NIL)
sour = sour->ch[flag];
return sour;
}
NODE *insert(int tn)
{
splay(ll, NIL);
splay(rl, root);
NODE *temp = extreme(rl, 0);
newnode(temp->ch[0], temp, tn);
splay(temp->ch[0], NIL);
return root;
}
void erase(NODE *sour)
{
splay(sour, NIL);
NODE *p1, *p2;
p1 = extreme(sour->ch[0], 1);
p2 = extreme(sour->ch[1], 0);
splay(p1, NIL);
splay(p2, root);
p2->ch[0] = NIL;
push_up(p2);
push_up(p1);
}
NODE *select(int r)
{
NODE *sour = root;
while(r != sour->ch[0]->size+1)
{
if(r <= sour->ch[0]->size)
sour = sour->ch[0];
else
{
r -= sour->ch[0]->size+1;
sour = sour->ch[1];
}
}
splay(sour, NIL);
return root;
}
};
struct HASH
{
struct NODE
{
int num;
NODE *next;
};
NODE *head[MOD];
NODE pool[MAXN];
NODE *rear;
void init()
{
memset(head, 0, sizeof(head));
rear = pool;
}
inline int hash(int num)
{
return num%MOD;
}
void insert(int num)
{
int h = hash(num);
for(NODE *i = head[h]; i; i = i->next)
if(i->num == num)
return;
rear->num = num;
rear->next = head[h];
head[h] = rear++;
}
bool search(int num)
{
int h = hash(num);
for(NODE *i = head[h]; i; i = i->next)
if(i->num == num)
return true;
return false;
}
};
struct ELE
{
int num;
SPLAY_TREE::NODE *ptr;
ELE()
{}
ELE(int tn, SPLAY_TREE::NODE *tp): num(tn), ptr(tp)
{}
friend bool operator < (const ELE &op1, const ELE &op2)
{
return op1.num < op2.num;
}
friend bool operator >= (const ELE &op1, const ELE &op2)
{
return op1.num >= op2.num;
}
friend bool operator <= (const ELE &op1, const ELE &op2)
{
return op1.num <= op2.num;
}
friend bool operator == (const ELE &op1, const ELE &op2)
{
return op1.num == op2.num;
}
friend bool operator != (const ELE &op1, const ELE &op2)
{
return op1.num != op2.num;
}
};
SBT<ELE> sbt;
SPLAY_TREE spt;
HASH hash_table;
int main()
{
int T;
scanf("%d", &T);
char str[10];
int op;
int n_case(0);
while(T--)
{
sbt.init();
spt.init();
hash_table.init();
int N, Q;
printf("Case %d:\n", ++n_case);
scanf("%d%d", &N, &Q);
for(int i = 0; i < Q; ++i)
{
scanf("%s%d", str, &op);
if(str[0] == 'T')
{
if(hash_table.search(op))
{
SBT<ELE>::NODE *p = sbt.search(ELE(op, NULL));
spt.erase(p->key.ptr);
p->key.ptr = spt.insert(op);
}
else
{
hash_table.insert(op);
SPLAY_TREE::NODE *p = spt.insert(op);
sbt.insert(ELE(op, p));
}
}
else
if(str[0] == 'Q')
{
if(hash_table.search(op))
{
SBT<ELE>::NODE *p = sbt.search(ELE(op, NULL));
spt.splay(p->key.ptr, spt.NIL);
printf("%d\n", spt.root->ch[0]->size);
}
else
{
int temp = sbt.rank(ELE(op, NULL));
printf("%d\n", op+(sbt.root->size-(temp-1)));
}
}
else
{
if(op <= sbt.root->size)
{
SPLAY_TREE::NODE *p = spt.select(op+1);
printf("%d\n", p->num);
}
else
{
// int temp = sbt.rank(ELE(op, NULL));
// int ret = op-(sbt.root->size-(temp-1));
// while(hash_table.search(ret))
// --ret;
printf("%d\n", sbt.fun(op));
}
}
}
}
return 0;
}