bzoj

链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3224
思路:想最初萌新入坑的时候看wf,那时候好像jls就是在敲一个splay?然后对从此觉得splay是非常高深的东西。。。最近初看,发现能懂一部分原理,这篇文章写的挺不错的。后面还会继续仔细看:
https://blog.csdn.net/a_comme_amour/article/details/79382104
然后放一个模板题在这里。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

using namespace std;

typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vp;
const int inf = 1e9;
const ll INF = 1e18;

#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define ep emplace
#define mem(a) memset(a, 0, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(b))
#define PA cout << "passn"
#define lowbit(x) (x & -x)
#define all(x) x.begin(), x.end()

const int maxn = 1e5 + 233;
int f[maxn], cnt[maxn], ch[maxn][2], sz[maxn], val[maxn], tag[maxn], idx, rt, n;

void (int x){
f[x] = cnt[x] = ch[x][0] = ch[x][1] = sz[x] = val[x] = 0;
}

bool get(int x){
return ch[f[x]][1] == x;
}

void pushup(int x){
if(x){
sz[x] = cnt[x];
if(ch[x][0]) sz[x] += sz[ch[x][0]];
if(ch[x][1]) sz[x] += sz[ch[x][1]];
}
}

void rotate(int x){
int fa = f[x], gf = f[fa], o = get(x);
ch[fa][o] = ch[x][o ^ 1];
f[ch[fa][o]] = fa;
ch[x][o ^ 1] = fa, f[fa] = x;
f[x] = gf;
if(gf) ch[gf][ch[gf][1] == fa] = x;
pushup(fa);
pushup(x);
}

void splay(int x, int e = 0){
for(int fa; (fa = f[x]) != e; rotate(x)){
if(f[fa] != e) rotate(get(x) == get(fa) ? fa : x);
}
if(!e) rt = x;
}

void insert(int x){
if(!rt){
idx++;
val[idx] = x;
rt = idx;
cnt[idx] = sz[idx] = 1;
f[idx] = ch[idx][0] = ch[idx][1] = 0;
return;
}
int now = rt, fa = 0;
while(1){
if(x == val[now]){
cnt[now]++;
pushup(now);
pushup(fa);
splay(now);
return;
}
fa = now;
now = ch[now][val[now] < x];
if(!now){
idx++;
sz[idx] = cnt[idx] = 1;
ch[idx][0] = ch[idx][1] = 0;
ch[fa][x > val[fa]] = idx;
f[idx] = fa;
val[idx] = x;
pushup(fa);
splay(idx);
return;
}
}
}

int rnk(int x){
int now = rt, ans = 0;
while(1){
if(x < val[now]) now = ch[now][0];
else{
ans += sz[ch[now][0]];
if(x == val[now]){
splay(now);
return ans + 1;
}
ans += cnt[now];
now = ch[now][1];
}
}
}

int kth(int x){
int now = rt;
while(1){
if(ch[now][0] && x <= sz[ch[now][0]]) now = ch[now][0];
else{
if(x <= sz[ch[now][0]] + cnt[now]) return val[now];
x -= sz[ch[now][0]] + cnt[now], now = ch[now][1];
}
}
}

int pre(){
int now = ch[rt][0];
while(ch[now][1]) now = ch[now][1];
return now;
}

int next(){
int now = ch[rt][1];
while(ch[now][0]) now = ch[now][0];
return now;
}

void del(int x){
rnk(x);
if(cnt[rt] > 1){
cnt[rt]--;
pushup(rt);
return;
}
if(!ch[rt][0] && !ch[rt][1]){
clear(rt);
rt = 0;
return;
}
if(!ch[rt][0]){
int t = rt;
rt = ch[rt][1];
f[rt] = 0;
clear(t);
return;
}
else if(!ch[rt][1]){
int t = rt;
rt = ch[rt][0];
f[rt] = 0;
clear(t);
return;
}
int t = rt;
int p = pre();
splay(p);
ch[rt][1] = ch[t][1];
f[ch[t][1]] = rt;
clear(t);
pushup(rt);
}

int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) {
int op, k;
cin >> op >> k;
if(op == 1) insert(k);
if(op == 2)del(k);
if(op == 3)cout << rnk(k) << 'n';
if(op == 4) cout << kth(k) << 'n';
if(op == 5) insert(k), cout << val[pre()] << 'n', del(k);
if(op == 6) insert(k), cout << val[next()] << 'n', del(k);
}
return 0;
}