伸展树是一种高效率的BST,通过单旋、一字旋、之字旋等操作,实现数据的高效插入、删除
#include <bits/stdc++.h>
#define io cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define LL long long
#define ULL unsigned long long
#define EPS 1e-8
#define INF 0x7fffffff
#define SUB -INF - 1
using namespace std;
const int M = 100005;
int cnt, root;
struct node
{
int fa, ls, rs, size;
char val;
} t[M];
void update(int u)
{
t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
}
char str[M] = {0};
int build(int l, int r, int f)
{
if (l > r)
return 0;
int mid = (l + r) >> 1;
int cur = ++cnt;
t[cur].fa = f;
t[cur].val = str[mid];
t[cur].ls = build(l, mid - 1, cur);
t[cur].rs = build(mid + 1, r, cur);
update(cur);
return cur;
}
int get(int x)
{
return t[t[x].fa].rs == x;
}
void rotate(int x)
{
int f = t[x].fa, g = t[f].fa, son = get(x);
if (son == 1)
{
t[f].rs = t[x].ls;
if (t[f].rs)
t[t[f].rs].fa = f;
}
else
{
t[f].ls = t[x].rs;
if (t[f].ls)
t[t[f].ls].fa = f;
}
t[f].fa = x;
if (son == 1)
t[x].ls = f;
else
t[x].rs = f;
t[x].fa = g;
if (g)
{
if (t[g].rs == f)
t[g].rs = x;
else
t[g].ls = x;
}
update(f);
update(x);
}
void splay(int x, int goal)
{
if (goal == 0)
root = x;
while (1)
{
int f = t[x].fa, g = t[f].fa;
if (f == goal)
break;
if (g != goal)
{
if (get(x) == get(f))
rotate(f);
else
rotate(x);
}
rotate(x);
}
update(x);
}
int kth(int k, int u)
{
if (k == t[t[u].ls].size + 1)
return u;
if (k <= t[t[u].ls].size)
return kth(k, t[u].ls);
if (k >= t[t[u].ls].size + 1)
return kth(k - t[t[u].ls].size - 1, t[u].rs);
return 0;
}
void Insert(int l, int len)
{
int x = kth(l, root), y = kth(l + 1, root);
splay(x, 0);
splay(y, x);
t[y].ls = build(1, len, y);
update(y);
update(x);
}
void del(int l, int r)
{
int x = kth(l, root), y = kth(r + 1, root);
splay(x, 0);
splay(y, x);
t[y].ls = 0;
update(y);
update(x);
}
void inorder(int u)
{
if (u == 0)
return;
inorder(t[u].ls);
cout << t[u].val;
inorder(t[u].rs);
}
int main()
{
t[1].size = 2, t[1].ls = 2;
t[2].size = 1, t[2].fa = 1;
root = 1, cnt = 2;
int pos = 1;
int n;
cin >> n;
while (n--)
{
int len;
char opt[10];
cin >> opt;
if (opt[0] == 'I')
{
cin >> len;
for (int i = 1; i <= len; i++)
{
char ch = getchar();
while (ch < 32 || ch > 126)
ch = getchar();
str[i] = ch;
}
Insert(pos, len);
}
if (opt[0] == 'D')
{
cin >> len;
del(pos, pos + len);
}
if (opt[0] == 'G')
{
cin >> len;
int x = kth(pos, root), y = kth(pos + len + 1, root);
splay(x, 0);
splay(y, x);
inorder(t[y].ls);
cout << endl;
}
if (opt[0] == 'M')
{
cin >> len;
pos = len + 1;
}
if (opt[0] == 'P')
pos--;
if (opt[0] == 'N')
pos++;
}
return 0;
}