FAQ
..................................
splay有那么慢么 为何cena测4.5s 交了就是TLE
学校机子应该没有bzoj的好吧.............
#include <cstdio>
#include <cmath>
#include <map>
#define LL long long
#define lp(i,j,k) for(int i = j;i <= k;++i)
std::map<int,int>SPL_ORD;//以 i 为编号的 点 在 splay的顺序
int re,n,m,x,y,a,cnt = 1,fr = 0,be = 100000000;char c;
int root = 1,ch[200020][2],fa[200020],sz[200020],num[200020],ord[200020];
int key[200020],L[200020],R[200020];//键值表示点号 LL为一个区间
inline int read () {
c = getchar();
re = 0;
while(c <= '9' && c >= '0') {
re *=10;
re += c - '0';
c = getchar();
}
return re;
}
inline void rot (int X,int d) {
int t = sz[X];
sz[X] = sz[fa[X]];
sz[fa[X]] -= t;
sz[fa[X]] += sz[ch[X][d]];
ch[fa[X]][d ^ 1] = ch[X][d];
if(ch[X][d])
fa[ch[X][d]] = fa[X];
t = fa[fa[X]];
fa[fa[X]] = X;
ch[X][d] = fa[X];
fa[X] = t;
if(!t)
return;
if(ch[t][0] == ch[X][d])
ch[t][0] = X;
else ch[t][1] = X;
}
inline void splay (int X) {
while(fa[X]) {
if(fa[fa[X]]) {
int d = ch[fa[fa[X]]][0] == fa[X];
if(ch[fa[X]][d] == X) {
rot(X,d ^ 1);
rot(X,d);
}
else {
rot(X,d);
rot(X,d);
}
}
else {
if(ch[fa[X]][1] == X)
rot(X,0);
else rot(X,1);
}
}
root = X;
}
inline void push_up (int X) {
if(L[X])
sz[X] = R[X] - L[X] + 1;
else sz[X] = 1;
sz[X] += sz[ch[X][0]] + sz[ch[X][1]];
}
inline void split (int poi,int X) {
int t1 = sz[ch[X][0]];
int t2 = sz[ch[X][1]];
if(L[X] != poi) {
++cnt;
ch[cnt][0] = ch[X][0];
if(ch[X][0])
fa[ch[X][0]] = cnt;
fa[cnt] = X;
ch[X][0] = cnt;
if(L[X] + 1 == poi)
ord[cnt] = num[cnt] = key[cnt] = L[X];
else {
L[cnt] = L[X];
R[cnt] = poi - 1;
}
sz[cnt] = sz[X] - t2 - (R[X] - poi + 1);
}
if(R[X] != poi) {
++cnt;
ch[cnt][1] = ch[X][1];
if(ch[X][1])
fa[ch[X][1]] = cnt;
fa[cnt] = X;
ch[X][1] = cnt;
if(poi + 1 == R[X])
ord[cnt] = num[cnt] = key[cnt] = R[X];
else {
L[cnt] = poi + 1;
R[cnt] = R[X];
}
sz[cnt] = sz[X] - t1 - (poi - L[X] + 1);
}
ord[X] = num[X] = key[X] = poi;
L[X] = R[X] = 0;
}
int find (int Ord,int X) {
if(L[X]) {
if(Ord >= L[X] && Ord <= R[X]) {
split(Ord,X);
return X;
}
else {
if(Ord > R[X])
return find(Ord,ch[X][1]);
else return find(Ord,ch[X][0]);
}
}
else {
if(ord[X] == Ord)
return X;
if(ord[X] > Ord)
return find(Ord,ch[X][0]);
return find(Ord,ch[X][1]);
}
}
int rank (int goal,int X,int now) {
now += sz[ch[X][1]];
if(L[X]) {
if(goal <= now + R[X] - L[X] && goal >= now) {
split(R[X] - goal + now,X);
return X;
}
else {
if(goal < now)
return rank(goal,ch[X][1],now - sz[ch[X][1]]);
return rank(goal,ch[X][0],now + R[X] - L[X] + 1);
}
}
else {
if(now == goal)
return X;
if(now > goal)
return rank(goal,ch[X][1],now - sz[ch[X][1]]);
return rank(goal,ch[X][0],now + 1);
}
}
int main () {
n = read();
m = read();
L[1] = root = 1;
R[1] = sz[1] = n;
lp(i,1,m) {
x = read();
if(x == 1) {
x = read();
y = read();
x -= a;
y -= a;
int t = SPL_ORD[x];
if(!t)
t = x;
SPL_ORD[y] = t;
splay(find(t,root));
a = n - sz[ch[root][1]];
printf("%d\n",a);
num[root] = y;
}
else {
if(x == 2) {
x = read();
x -= a;
int t = SPL_ORD[x];
if(!t)
t = x;
splay(find(t,root));
a = n - sz[ch[root][1]];
printf("%d\n",a);
t = ch[root][0];
if(t) {
while(ch[t][1])
t = ch[t][1];
splay(t);
int SPL_poi = ch[root][1];
ch[root][1] = ch[SPL_poi][1];
if(ch[SPL_poi][1])
fa[ch[SPL_poi][1]] = root;
push_up(root);
fa[SPL_poi] = 0;
ch[SPL_poi][1] = root;
fa[root] = SPL_poi;
root = SPL_poi;
//push_up(root);
sz[root] = sz[ch[root][0]] + sz[ch[root][1]] + 1;
SPL_ORD[num[root]] = --fr;
ord[root] = fr;
}
}
else {
if(x == 3) {
x = read();
x -= a;
int t = SPL_ORD[x];
if(!t)
t = x;
splay(find(t,root));
a = n - sz[ch[root][1]];
printf("%d\n",a);
t = ch[root][1];
if(t) {
while(ch[t][0])
t = ch[t][0];
splay(t);
int SPL_poi = ch[root][0];
ch[root][0] = ch[SPL_poi][0];
if(ch[SPL_poi][0])
fa[ch[SPL_poi][0]] = root;
push_up(root);
fa[SPL_poi] = 0;
ch[SPL_poi][0] = root;
fa[root] = SPL_poi;
root = SPL_poi;
//push_up(root);
sz[root] = sz[ch[root][0]] + sz[ch[root][1]] + 1;
SPL_ORD[num[root]] = ++be;
ord[root] = be;
}
}
else {
x = read();
x -= a;
a = rank(n - x + 1,root,1);
splay(a);
a = num[root];
printf("%d\n",a);
}
}
}
}
}