社区讨论
Splay求条
P1486[NOI2004] 郁闷的出纳员参与者 4已保存回复 14
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @mioisoub
- 此快照首次捕获于
- 2025/12/02 19:54 3 个月前
- 此快照最后确认于
- 2025/12/02 20:24 3 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1100010,INF = (1<<30)+1;
int ch[N][2],cnt[N],siz[N],val[N],fa[N],tot,root,minn;
void pushup(int u){siz[u] = siz[ch[u][0]]+siz[ch[u][1]]+cnt[u];}
void rotate(int x){
int y = fa[x],z = fa[y];
int k = (ch[y][1]==x);
ch[y][k] = ch[x][k^1],fa[ch[x][k^1]] = y;
ch[x][k^1] = y,fa[y] = x;
ch[z][ch[z][1]==y] = x,fa[x] = z;
pushup(y);
pushup(x);
}
void splay(int x,int k){
int y,z;
while(fa[x]!=k){
y = fa[x],z = fa[y];
if(z!=k)(ch[y][0]==x)^(ch[z][0]==y)?rotate(x):rotate(y);
rotate(x);
}
if(!k)root = x;
}
void find1(int v){
int x = root;
while(ch[x][v>val[x]]&&val[x]!=v)x = ch[x][v>val[x]];
splay(x,0);
}
int getpre(int v){
find1(v);
int x = root;
if(val[x]<v)return x;
x = ch[x][0];
while(ch[x][1])x = ch[x][1];
splay(x,0);
return x;
}
int getsuc(int v){
find1(v);
int x = root;
if(val[x]>v)return x;
x = ch[x][1];
while(ch[x][0])x = ch[x][0];
splay(x,0);
return x;
}
void del(int v){
int p = getpre(v),s = getsuc(v);
splay(p,0);
splay(s,p);
int d = ch[s][0];
if(cnt[d]>1){
cnt[d]--;
splay(d,0);
}
else{
ch[s][0] = 0;
splay(s,0);
}
}
void insert(int v){
int x = root,p = 0;
while(x&&val[x]!=v)p = x,x = ch[x][v>val[x]];
if(x)cnt[x]++;
else{
x = ++tot;
ch[p][v>val[p]] = x;
fa[x] = p;
val[x] = v;
cnt[x] = siz[x] = 1;
}
splay(x,0);
}
int getrank(int v){
insert(v);
int ans = siz[ch[root][0]];
del(v);
return ans;
}
int getval(int k){
int x = root,y;
while(1){
y = ch[x][1];
if(k<=siz[y]&&y)x = y;
else if(k<=siz[y]+cnt[x])break;
else k = k-siz[y]-cnt[x],x = ch[x][0];
}
splay(x,0);
return val[x];
}
int main(){
cin.tie(0)->sync_with_stdio(0);
cout.tie(0);
insert(INF);
int n,x,ans = 0;
char op;
cin>>n>>minn;
for(int i = 1;i<=n;i++){
cin>>op;
cin>>x;
if(op=='I'&&x>=minn)insert(x);
else if(op=='A')for(int i = 1;i<=tot;i++)val[i]+=x;
else if(op=='S'){
int s = getsuc(x+minn-1);
splay(s,0);
ans+=siz[ch[root][0]];
ch[root][0] = 0;
siz[root]-=siz[ch[root][0]];
for(int i = 1;i<=tot;i++)val[i]-=x;
}
else {
if(x>=siz[root])cout<<-1<<'\n';
else cout<<getval(x+1)<<'\n';
}
}
cout<<ans;
return 0;
}
第三个输出总是代码中INF的值,就是不输出-1。
回复
共 14 条回复,欢迎继续交流。
正在加载回复...