题目链接
一个学习splay的链接,挺不错的哟。
初识splay的时间里,总是会在各种各样的地方反着各种各样稀奇古怪的错误,好蒻……
这次的错误是在pushup()的时候,我们更新其父节点的时候,不能直接使用"+1"来做,而是要理解为什么是加上这个节点的cnt的值。然后就是一顿splay的模板了,模板供参考啦…… QAQ。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, root, tot;
struct node
{
int ff, val, cnt, size, ch[2];
node() { ff = val = size = ch[0] = ch[1] = 0; }
void init(int vv, int fa)
{
ff = fa; val = vv;
ch[0] = ch[1] = 0;
size = cnt = 1;
}
}t[maxN];
void pushup(int rt) { t[rt].size = t[t[rt].ch[0]].size + t[t[rt].ch[1]].size + t[rt].cnt; }
void Rotate(int x)
{
int y = t[x].ff, z = t[y].ff;
int k = t[y].ch[1] == x;
t[z].ch[t[z].ch[1] == y] = x;
t[x].ff = z;
t[y].ch[k] = t[x].ch[k^1];
t[t[x].ch[k^1]].ff = y;
t[x].ch[k^1] = y;
t[y].ff = x;
pushup(y); pushup(x);
}
void Splay(int x, int goal)
{
while(t[x].ff != goal)
{
int y = t[x].ff, z = t[y].ff;
if(z != goal) (t[z].ch[0] == y) ^ (t[y].ch[0] == x) ? Rotate(x) : Rotate(y);
Rotate(x);
}
if(!goal) root = x;
}
void insert(int x)
{
int u = root, ff = 0;
while(u && t[u].val != x)
{
ff = u;
u = t[u].ch[x>t[u].val];
}
if(u) t[u].cnt++;
else
{
u = ++tot;
if(ff) t[ff].ch[x>t[ff].val] = u;
t[u].init(x, ff);
}
Splay(u, 0);
}
void Find(int x)
{
int u = root;
if(!u) return;
while(t[u].ch[x>t[u].val] && x != t[u].val) u = t[u].ch[x>t[u].val];
Splay(u, 0);
}
int Next(int x, int f)
{
Find(x);
int u = root;
if(t[u].val > x && f) return u;
if(t[u].val < x && !f) return u;
u = t[u].ch[f];
while(t[u].ch[f^1]) u = t[u].ch[f^1];
return u;
}
void Delete(int x)
{
int last = Next(x, 0), next = Next(x, 1);
Splay(last, 0); Splay(next, last);
int del = t[next].ch[0];
if(t[del].cnt > 1)
{
t[del].cnt--;
Splay(del, 0);
}
else t[next].ch[0] = 0;
}
int Kth(int x)
{
int u = root;
if(t[u].size < x) return 0; //不存在
while(true)
{
int y = t[u].ch[0];
if(x > t[u].cnt + t[y].size)
{
x -= t[u].cnt + t[y].size;
u = t[u].ch[1];
}
else
{
if(x <= t[y].size) u = y;
else return u;
}
}
}
int main()
{
scanf("%d", &N);
int op, x;
root = tot = 0;
insert(-INF);
insert(INF);
while(N--)
{
scanf("%d%d", &op, &x);
if(op == 1) insert(x);
else if(op == 2) Delete(x);
else if(op == 3)
{
Find(x);
printf("%d\n", t[t[root].ch[0]].size);
}
else if(op == 4) printf("%d\n", t[Kth(x+1)].val);
else if(op == 5)
{
int last = Next(x, 0);
printf("%d\n", t[last].val);
}
else
{
int next = Next(x, 1);
printf("%d\n", t[next].val);
}
}
return 0;
}
/*
20
1 964673
5 968705
4 1
3 964673
5 965257
1 915269
1 53283
3 964673
3 53283
3 53283
1 162641
5 973984
1 948119
2 915269
2 53283
6 959161
1 531821
1 967521
2 531821
1 343410
ans:
964673
964673
1
964673
3
1
1
964673
964673
*/