splay
作业介绍
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5,Inf=1e9+10;
struct node {
int ch[2],fa,val,size,cnt;
//ch[0]左儿子,ch1右儿子,val值,size子树大小
}tree[N];
int n,root,tot;
void pushup(int x) {
//更新size
if (!x)return;
tree[x].size = tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+tree[x].cnt;
}
int Get(int x) {
//返回x为左儿子还是右儿子
return x == tree[tree[x].fa].ch[1];
}
void rotate(int x) {
//将x旋转到x的父亲之上
int y = tree[x].fa,z=tree[y].fa,chk=Get(x);
tree[y].ch[chk] = tree[x].ch[chk^1];
if (tree[x].ch[chk^1])tree[tree[x].ch[chk^1]].fa = y;
tree[x].ch[chk^1] = y;
tree[y].fa = x;
if (z)tree[z].ch[y==tree[z].ch[1]] = x;
tree[x].fa = z;
pushup(y);
pushup(x);
}
void splay(int x,int k) {
//将x旋转至k的儿子
while (tree[x].fa!=k) {
int y = tree[x].fa,z=tree[y].fa;
if (z!=k) {
if (Get(x)==Get(y))rotate(y);
else rotate(x);
}
rotate(x);
}
if (k==0)root = x;
}
void insert(int x) {
//插入x
int cur = root;
int fa = 0;
while (cur) {
if (tree[cur].val==x) {
tree[cur].cnt++;
pushup(cur);
pushup(fa);
splay(cur,0);
return;
}
fa = cur;
cur = tree[cur].ch[x>tree[cur].val];
}
cur = ++tot;
tree[cur].fa = fa;
tree[cur].cnt = 1;
tree[cur].val = x;
tree[fa].ch[x>tree[fa].val] = cur;
pushup(cur);
pushup(fa);
splay(cur,0);
}
int rnk(int x) {
int cur = root,res=0;
while (cur) {
if (x<tree[cur].val)cur = tree[cur].ch[0];
else {
res+=tree[tree[cur].ch[0]].size;
if (tree[cur].val==x) {
splay(cur,0);
return res+1;
}
else {
res+=tree[cur].cnt;
cur = tree[cur].ch[1];
}
}
}
return res+1;
}
int kth(int x) {
//查找排名为x的数
int cur = root;
while (cur) {
if (x<=tree[tree[cur].ch[0]].size)cur=tree[cur].ch[0];
else {
x-=tree[tree[cur].ch[0]].size;
if (x<=tree[cur].cnt) {
splay(cur,0);
return cur;
}
else {
x-=tree[cur].cnt;
cur = tree[cur].ch[1];
}
}
}
return -1;
}
int pre(int x) {
//查找x的前驱
int cur = root,res=-Inf;
while (cur) {
if (tree[cur].val<x) {
res = max(res,tree[cur].val);
cur = tree[cur].ch[1];
}
else cur=tree[cur].ch[0];
}
return res;
}
int nxt(int x) {
int cur = root,res=Inf;
while (cur) {
if (tree[cur].val>x) {
res = min(res,tree[cur].val);
cur = tree[cur].ch[0];
}
else cur = tree[cur].ch[1];
}
return res;
}
void find(int x) {
//让x旋转到根
int cur=root;
while (cur) {
if (tree[cur].val==x) {
splay(cur,0);
return;
}
cur = tree[cur].ch[x>tree[cur].val];
}
}
void del(int x) {
find(x);
int L=tree[root].ch[0],R=tree[root].ch[1];
while (tree[L].ch[1])L=tree[L].ch[1];
while (tree[R].ch[0])R=tree[R].ch[0];
splay(L,0);
splay(R,L);
if (tree[tree[R].ch[0]].cnt>1) {
tree[tree[R].ch[0]].cnt--;
pushup(tree[R].ch[0]);
}
else {
tree[R].ch[0] = 0;
}
pushup(R);
pushup(L);
}
int main() {
cin>>n;
insert(-Inf),insert(Inf);
while (n--) {
int op,x;
cin>>op>>x;
if (op==1) {
insert(x);
}
else if (op==2)del(x);
else if (op==3)cout<<rnk(x)-1<<endl;
else if (op==4)cout<<tree[kth(x+1)].val<<endl;
else if (op==5)cout<<pre(x)<<endl;
else cout<<nxt(x)<<endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n,m,tot,root;
struct node {
int ch[2],val,size,fa;
int rev;
}tree[N];
void pushup(int x) {
if (!x)return ;
tree[x].size = tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1;
}
void pushrev(int x) {
tree[x].rev^=1;
swap(tree[x].ch[0],tree[x].ch[1]);
}
void pushdown(int x) {
if (tree[x].rev) {
pushrev(tree[x].ch[0]);
pushrev(tree[x].ch[1]);
tree[x].rev=0;
}
}
int Get(int x) {
return x == tree[tree[x].fa].ch[1];
}
void rotate(int x) {
int y = tree[x].fa,z=tree[y].fa,chk=Get(x);
tree[y].ch[chk] = tree[x].ch[chk^1];
if (tree[x].ch[chk^1])tree[tree[x].ch[chk^1]].fa = y;
tree[x].ch[chk^1] = y;
tree[y].fa = x;
if (z)tree[z].ch[y==tree[z].ch[1]] = x;
tree[x].fa = z;
pushup(y);
pushup(x);
}
void splay(int x,int k) {
while (tree[x].fa!=k) {
int y = tree[x].fa,z=tree[y].fa;
if (z!=k) {
if (Get(x)==Get(y))rotate(y);
else rotate(x);
}
rotate(x);
}
if (k==0)root = x;
}
void insert(int x) {
int cur = root,fa=0;
while (cur) {
fa= cur;
cur = tree[cur].ch[x>tree[cur].val];
}
cur = ++tot;
tree[cur].val = x;
tree[cur].fa = fa;
tree[fa].ch[x>tree[fa].val] = cur;
pushup(cur);
pushup(fa);
splay(cur,0);
}
int kth(int x) {
int cur = root;
while (cur) {
pushdown(cur);
if (x<=tree[tree[cur].ch[0]].size)cur = tree[cur].ch[0];
else {
x-=tree[tree[cur].ch[0]].size;
if (x<=1) {
splay(cur,0);
return cur;
}
else {
x--;
cur = tree[cur].ch[1];
}
}
}
return -1;
}
void Rev(int l,int r) {
int L = kth(l);
int R = kth(r+2);
splay(L,0);
splay(R,L);
pushrev(tree[R].ch[0]);
}
void print(int x) {
pushdown(x);
if (!x)return;
if (tree[x].ch[0])print(tree[x].ch[0]);
if (tree[x].val>=1&&tree[x].val<=n)cout<<tree[x].val<<" ";
if (tree[x].ch[1])print(tree[x].ch[1]);
}
int main() {
cin>>n>>m;
for (int i=0;i<=n+1;i++) {
insert(i);
}
while (m--) {
int x,y;
cin>>x>>y;
Rev(x,y);
}
print(root);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5, Inf = 1e12;
struct node {
int ch[2], fa, val, size, cnt;
} tree[N];
int n, m, q, root, tot;
int delta;
void pushup(int x) {
if (!x)
return;
tree[x].size = tree[tree[x].ch[0]].size + tree[tree[x].ch[1]].size + tree[x].cnt;
}
int Get(int x) {
return x == tree[tree[x].fa].ch[1];
}
void rotate(int x) {
int y = tree[x].fa, z = tree[y].fa;
int chk = Get(x);
tree[y].ch[chk] = tree[x].ch[chk ^ 1];
if (tree[x].ch[chk ^ 1])
tree[tree[x].ch[chk ^ 1]].fa = y;
tree[x].ch[chk ^ 1] = y;
tree[y].fa = x;
if (z)
tree[z].ch[y == tree[z].ch[1]] = x;
tree[x].fa = z;
pushup(y);
pushup(x);
}
void splay(int x, int k) {
while (tree[x].fa != k) {
int y = tree[x].fa, z = tree[y].fa;
if (z != k) {
if (Get(x) == Get(y))
rotate(y);
else
rotate(x);
}
rotate(x);
}
if (k == 0)
root = x;
}
void insert(int x) {
int cur = root;
int fa = 0;
while (cur) {
if (tree[cur].val == x) {
tree[cur].cnt++;
pushup(cur);
pushup(fa);
splay(cur, 0);
return;
}
fa = cur;
cur = tree[cur].ch[x > tree[cur].val];
}
cur = ++tot;
tree[cur].val = x;
tree[cur].fa = fa;
tree[cur].cnt = 1;
tree[fa].ch[x > tree[fa].val] = cur;
pushup(cur);
pushup(fa);
splay(cur, 0);
}
int kth(int x) {
int cur = root;
while (cur) {
if (x <= tree[tree[cur].ch[0]].size)
cur = tree[cur].ch[0];
else {
x -= tree[tree[cur].ch[0]].size;
if (x <= tree[cur].cnt) {
splay(cur, 0);
return cur;
} else {
x -= tree[cur].cnt;
cur = tree[cur].ch[1];
}
}
}
return -1;
}
int nxt(int x) {
int cur = root;
int res = Inf + 1, id = -1;
while (cur) {
// cout << cur << endl;
if (tree[cur].val > x) {
if (tree[cur].val < res) {
id = cur;
res = tree[cur].val;
}
cur = tree[cur].ch[0];
} else
cur = tree[cur].ch[1];
}
return id;
}
void print(int x) {
cout << x << ' ' << tree[x].val << " " << tree[x].ch[0] << " " << tree[x].ch[1] << endl;
if (tree[x].ch[0])
print(tree[x].ch[0]);
if (tree[x].ch[1])
print(tree[x].ch[1]);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
int res = 0;
insert(-Inf);
insert(Inf);
for (int i = 1; i <= n; i++) {
char pos;
int x;
cin >> pos >> x;
if (pos == 'I') {
if (x >= m) {
insert(x - delta);
}
} else if (pos == 'A') {
delta += x;
} else if (pos == 'S') {
delta -= x;
//有多少个工资+delta<m
//找工资<m-delta的
// print(root);
int L = 1, R = nxt(m - delta - 1);
splay(L, 0);
splay(R, L);
res += tree[tree[R].ch[0]].size;
tree[R].ch[0] = 0;
pushup(R);
pushup(L);
} else {
if (x > tree[root].size - 2)
cout << -1 << endl;
else
cout << tree[kth(tree[root].size - x)].val + delta << endl;
}
}
cout << res << endl;
return 0;
}
题目
认领作业后才可以查看作业内容。
- 状态
- 正在进行…
- 题目
- 8
- 开始时间
- 2026-7-31 0:00
- 截止时间
- 2026-8-31 23:59
- 可延期
- 24 小时