bzoj1861 书架
Posted wxyww
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1861 书架相关的知识,希望对你有一定的参考价值。
思路
用一个平衡树维护点的编号和权值。这里的权值是自己赋上去的。
操作1,就把x从平衡树中删掉,然后将其权值变为最小值,重新插入。
操作2,与操作1类似,只要将其权值变为最大值再重新插入就行了。
操作3,其实就是将x与他的前驱或者后继交换。也很容易实现。
操作4,查询排名。
操作5,查找第k大。
代码
/*
* @Author: wxyww
* @Date: 2019-05-25 10:50:13
* @Last Modified time: 2019-05-25 17:21:41
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
#define ls TR[cur].ch[0]
#define rs TR[cur].ch[1]
const int N = 500000 + 100,INF = 1e9 + 10;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
struct node {
int ch[2],val,id,key,siz;
}TR[N];
int tot;
int root,dy[N];
void up(int cur) {
TR[cur].siz = TR[ls].siz + TR[rs].siz + 1;
}
void rotate(int &cur,int f) {
int son = TR[cur].ch[f];
TR[cur].ch[f] = TR[son].ch[f ^ 1];
TR[son].ch[f ^ 1] = cur;
up(cur);
cur = son;
up(cur);
}
void insert(int &cur,int val,int key) {
if(!cur) {
cur = ++tot;
TR[cur].val = val;TR[cur].key = key;
TR[cur].id = rand();TR[cur].siz = 1;
dy[key] = cur;
return;
}
TR[cur].siz++;
int d = val > TR[cur].val;
insert(TR[cur].ch[d],val,key);
if(TR[TR[cur].ch[d]].id < TR[cur].id) rotate(cur,d);
}
void del(int &cur,int val) {
if(!cur) return;
if(val == TR[cur].val) {
if(!ls || !rs) {cur = ls + rs;return;}
int d = TR[rs].id < TR[ls].id;rotate(cur,d);
del(cur,val);
}
else TR[cur].siz--,del(TR[cur].ch[val > TR[cur].val],val);
}
int Rank(int cur,int val) {
if(!cur) return 0;
if(val == TR[cur].val) return TR[ls].siz;
if(val < TR[cur].val) return Rank(ls,val);
else return Rank(rs,val) + TR[ls].siz + 1;
}
int kth(int cur,int now) {
while(1) {
if(TR[ls].siz >= now) cur = ls;
else if(TR[ls].siz + 1 == now) return TR[cur].key;
else now -= TR[ls].siz + 1,cur = rs;
}
}
int pred(int cur,int val) {
if(!cur) {
TR[++tot].val = -INF;
return tot;
}
if(val <= TR[cur].val) return pred(ls,val);
int k = pred(rs,val);
return TR[k].val > TR[cur].val ? k : cur;
}
int nex(int cur,int val) {
if(!cur) {
TR[++tot].val = INF;
return tot;
}
if(val >= TR[cur].val) return nex(rs,val);
int k = nex(ls,val);
return TR[k].val < TR[cur].val ? k : cur;
}
int LL,RR,a[N];
char S[10];
int main() {
srand(time(0));
int n = read(),m = read();
for(int i = 1;i <= n;++i) {
int x = read();
a[x] = i,insert(root,++RR,x);
}
while(m--) {
scanf("%s",S + 1);
if(S[1] == 'T') {
int x = read();
del(root,a[x]);
a[x] = --LL;
insert(root,LL,x);
}
else if(S[1] == 'B') {
int x = read();
del(root,a[x]);a[x] = ++RR;
insert(root,RR,x);
}
else if(S[1] == 'I') {
int x = read(),y = read();
if(!y) continue;
int tmp;
if(y == -1) tmp = pred(root,a[x]);
else tmp = nex(root,a[x]);
int zz = TR[tmp].key;
swap(TR[tmp].key,TR[dy[x]].key);
// printf("!!%d %d\n",x,zz);
swap(dy[x],dy[zz]);
swap(a[x],a[zz]);
}
else if(S[1] == 'A') {
int x = read();
printf("%d\n",Rank(root,a[x]));
}
else {
int x = read();
printf("%d\n",kth(root,x));
}
}
return 0;
}
以上是关于bzoj1861 书架的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1861 [Zjoi2006]Book 书架 ——Splay