社区讨论
Splay 求助,洛谷 AC,模拟赛 WA
P2596[ZJOI2006] 书架参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lo7iifpf
- 此快照首次捕获于
- 2023/10/27 02:22 2 年前
- 此快照最后确认于
- 2023/10/27 02:22 2 年前
CPP
#include <bits/stdc++.h>
#define gc IO::fastgc()
#define pc(c) putchar(c)
typedef long long ll;typedef long long unsigned llu,ull;typedef long double lf;
using namespace std;
constexpr unsigned N=5e6+7;
int n,m;
ll p[N];
int pos[N];
int rcl[N],rtop;
struct Node{
ll v;
int s[2],p,sz;
void init(ll vv,int pp){
v=vv,
s[0]=s[1]=0,
p=pp,
sz=1;
}
}tr[N];
int rt,ncnt;
void out(int);
int newnode(){
if(rtop){
return rcl[rtop--];
}
return ++ncnt;
}
inline void pushup(int u){
tr[u].sz=tr[tr[u].s[0]].sz+tr[tr[u].s[1]].sz+1;
}
inline void rotate(int x){
int y=tr[x].p;
int z=tr[y].p;
int k=(tr[y].s[1]==x),p=(tr[z].s[1]==y);
tr[z].s[p]=x,tr[x].p=z;
tr[y].s[k]=tr[x].s[k^1],tr[tr[x].s[k^1]].p=y;
tr[x].s[k^1]=y,tr[y].p=x;
pushup(y),
pushup(x);
}
inline void splay(int x,int k){
while(tr[x].p!=k){
int y=tr[x].p;
int z=tr[y].p;
if(z!=k){
if((tr[y].s[1]==x)^(tr[z].s[1]==y)){
rotate(x);
}
else{
rotate(y);
}
}
rotate(x);
}
if(!k){
rt=x;
}
}
int build(int l,int r){
int mid=(l+r)>>1,u=newnode();
tr[u].init(p[mid],0);
pos[p[mid]]=u;
if(l<=mid-1){
tr[u].s[0]=build(l,mid-1),
tr[tr[u].s[0]].p=u;
}
if(r>=mid+1){
tr[u].s[1]=build(mid+1,r);
tr[tr[u].s[1]].p=u;
}
pushup(u);
return u;
}
inline int query(int x){
int u=rt,s0;
while(1){
s0=tr[tr[u].s[0]].sz;
if(s0+1==x){
splay(u,0);
return u;
}
else if(s0>=x){
u=tr[u].s[0];
}
else{
u=tr[u].s[1];
x-=s0+1;
}
}
}
int ask(int p){
splay(p,0);
return tr[tr[rt].s[0]].sz;
}
void insert(int p,ll v){
int x=query(p+1),y=query(p+2);
splay(x,0),
splay(y,x);
tr[y].s[0]=newnode();
tr[tr[y].s[0]].init(v,y);
pos[v]=tr[y].s[0];
pushup(y);
pushup(x);
splay(tr[y].s[0],0);
}
void del(int p){
int ps=ask(p);
int x=query(ps),y=query(ps+2);
splay(x,0),
splay(y,x);
pos[tr[tr[y].s[0]].v]=-1;
rcl[++rtop]=tr[y].s[0];
tr[y].s[0]=0;
pushup(y);
pushup(x);
}
int main(){
freopen("book.in","r",stdin),
freopen("book.out","w",stdout);
int s,t;
static char op[17];
scanf("%d%d",&n,&m);
p[1]=p[n+2]=0;
for(int i=2;i<=n+1;++i){
scanf("%lld",p+i);
}
rt=build(1,n+2);
while(m--){
scanf("%s",op);
switch(op[0]){
case 'T':
case '1':{
scanf("%d",&s);
del(pos[s]);
insert(0,s);
break;
}
case 'B':
case '2':{
scanf("%d",&s);
del(pos[s]);
insert(n-1,s);
break;
}
case 'I':
case '3':{
scanf("%d%d",&s,&t);
int np=ask(pos[s])+t;
del(pos[s]);
insert(np-1,s);
break;
}
case 'A':
case '4':{
scanf("%d",&s);
printf("%d\n",ask(pos[s])-1);
break;
}
case 'Q':
case '5':{
scanf("%d",&s);
printf("%lld\n",tr[query(s+1)].v);
break;
}
}
}
return 0;
}
模拟赛的题就只是把范围加到 ,操作改成
12345。回复
共 2 条回复,欢迎继续交流。
正在加载回复...