fhq-treap为什么这样做就对了
查看原帖
fhq-treap为什么这样做就对了
605945
luo_xiaoran楼主2024/3/4 09:35

AC代码:

#include<bits/stdc++.h>
#define N (int)1e5+5
using namespace std;
int ans,sum,mn,n,cnt,ch[N][2],siz[N],val[N],pri[N];
mt19937 rd(time(0));
int New(int x){
    siz[++cnt]=1;
    val[cnt]=x;
    pri[cnt]=rd();
    return cnt;
}
void update(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
void split(int now,int k,int &x,int &y){
    if(!now) x=y=0;
    else{
        if(val[now]+sum<=k) x=now,split(ch[now][1],k,ch[now][1],y);
        else y=now,split(ch[now][0],k,x,ch[now][0]);
        update(now);
    }
}
int merge(int x,int y){
    if((!x)||(!y)) return x+y;
    if(pri[x]<pri[y]){
        ch[x][1]=merge(ch[x][1],y);
        update(x);
        return x;
    }
    else{
        ch[y][0]=merge(x,ch[y][0]);
        update(y);
        return y;
    }
}
int rk(int now,int k){
	while(1){
		if(k<=siz[ch[now][0]]) now=ch[now][0];
        else if(k==siz[ch[now][0]]+1) return now;
        else k-=(siz[ch[now][0]]+1),now=ch[now][1];
    }
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
    int x,y,root=0;
    cin>>n>>mn;
    while(n--){
		int a;
        char opt;
        cin>>opt>>a;
        if(opt=='I'&&a>=mn) a-=sum,split(root,a,x,y),root=merge(merge(x,New(a)),y);
        else if(opt=='A') sum+=a;
        else if(opt=='S') sum-=a,split(root,mn-1,x,y),root=y,ans+=siz[x];
        else if(opt=='F'&&a<=siz[root]) cout<<val[rk(root,siz[root]-a+1)]+sum<<endl;
        else if(opt=='F') cout<<-1<<endl;
    }
    cout<<ans;
    return 0;
}

WA10分代码:

#include<bits/stdc++.h>
#define N (int)1e5+5
using namespace std;
int ans,sum,mn,n,cnt,ch[N][2],siz[N],val[N],pri[N];
mt19937 rd(time(0));
int New(int x){
    siz[++cnt]=1;
    val[cnt]=x;
    pri[cnt]=rd();
    return cnt;
}
void update(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
void split(int now,int k,int &x,int &y){
    if(!now) x=y=0;
    else{
        if(val[now]<=k) x=now,split(ch[now][1],k,ch[now][1],y);
        else y=now,split(ch[now][0],k,x,ch[now][0]);
        update(now);
    }
}
int merge(int x,int y){
    if((!x)||(!y)) return x+y;
    if(pri[x]<pri[y]){
        ch[x][1]=merge(ch[x][1],y);
        update(x);
        return x;
    }
    else{
        ch[y][0]=merge(x,ch[y][0]);
        update(y);
        return y;
    }
}
int rk(int now,int k){
	while(1){
		if(k<=siz[ch[now][0]]) now=ch[now][0];
        else if(k==siz[ch[now][0]]+1) return now;
        else k-=(siz[ch[now][0]]+1),now=ch[now][1];
    }
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
    int x,y,root=0;
    cin>>n>>mn;
    while(n--){
		int a;
        char opt;
        cin>>opt>>a;
        if(opt=='I'&&a>=mn) a-=sum,split(root,a,x,y),root=merge(merge(x,New(a)),y);
        else if(opt=='A') sum+=a;
        else if(opt=='S') sum-=a,split(root,mn-1-sum,x,y),root=y,ans+=siz[x];
        else if(opt=='F'&&a<=siz[root]) cout<<val[rk(root,siz[root]-a+1)]+sum<<endl;
        else if(opt=='F') cout<<-1<<endl;
    }
    cout<<ans;
    return 0;
}

将

else if(opt=='S') sum-=a,split(root,mn-1,x,y),root=y,ans+=siz[x];

和

if(val[now]+sum<=k) x=now,split(ch[now][1],k,ch[now][1],y);

改为

else if(opt=='S') sum-=a,split(root,mn-1-sum,x,y),root=y,ans+=siz[x];

和

if(val[now]<=k) x=now,split(ch[now][1],k,ch[now][1],y);

就对了,这是为什么?

2024/3/4 09:35
加载中...