此为未经优化AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 100005
int n,m,minn=1,maxn;
int root,vl[N],w[N],siz[N],lr[N][2];
int neww(int val,int x){
vl[x]=val;
w[x]=rand();
siz[x]=1;
return x;
}
void pushup(int p){siz[p]=siz[lr[p][0]]+siz[lr[p][1]]+1;}
void split(int p,int val,int &x,int &y){
if(!p){x=y=0;return;}
if(vl[p]<=val)x=p,split(lr[p][1],val,lr[p][1],y);
else y=p,split(lr[p][0],val,x,lr[p][0]);
pushup(p);
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(w[x]<w[y]){
lr[x][1]=merge(lr[x][1],y);
pushup(x);
return x;
}
else{
lr[y][0]=merge(x,lr[y][0]);
pushup(y);
return y;}
}
void insert(int &root,int val,int X){
int x,y;
split(root,val,x,y);
root=merge(merge(x,neww(val,X)),y);
}
void change(int val,int newval){
int x,y,z;
split(root,val,x,y);
split(x,val-1,x,z);
vl[z]=newval;
if(newval==minn)root=merge(merge(z,x),y);
else root=merge(merge(x,y),z);
}
int pre(int val){
int x,y,p;
split(root,val-1,x,y);p=x;
while(lr[p][1]) p=lr[p][1];
root=merge(x,y);
return p;
}
int last(int val){
int x,y,p;
split(root,val,x,y);
p=y;
while(lr[p][0]) p=lr[p][0];
root=merge(x,y);
return p;
}
void swp(int x,int y){
swap(vl[x],vl[y]);
swap(w[x],w[y]);
swap(siz[x],siz[y]);
swap(lr[x][0],lr[y][0]);
swap(lr[x][1],lr[y][1]);
}
void b_insert(int k,int val)
{
if(!val) return;
int t,x,y,z,a;
if(val<0){
t=pre(vl[k]);
split(root,vl[t],x,y);
split(x,vl[t]-1,x,z);
split(y,vl[k],y,a);
swp(y,z);
root=merge(x,merge(y,merge(z,a)));
}
else{
t=last(vl[k]);
split(root,vl[k],x,y);
split(x,vl[k]-1,x,z);
split(y,vl[t],y,a);
swp(y,z);
root=merge(x,merge(y,merge(z,a)));
}
}
int rank(int val){
int x,y,res;
split(root,val-1,x,y);res=siz[x]+1;
root=merge(x,y);
return res;
}
int kth(int k){
int p=root;
while(1)
if(k<=siz[lr[p][0]]) p=lr[p][0];
else if(k==siz[lr[p][0]]+1)return p;
else k-=siz[lr[p][0]]+1,p=lr[p][1];
}
int main(){
char f[15];
srand(time(0));
scanf("%d%d",&n,&m);
maxn=n;
for(int i=1;i<=n;++i){
int a;
scanf("%d",&a);
insert(root,i,a);
}
while(m--){
int a,b;
scanf("%s",f);
if(f[0]=='T')scanf("%d",&a),change(vl[a],--minn);
if(f[0]=='B')scanf("%d",&a),change(vl[a],++maxn);
if(f[0]=='I')scanf("%d%d",&a,&b),b_insert(a,b);
if(f[0]=='A')scanf("%d",&a),printf("%d\n",rank(vl[a])-1);
if(f[0]=='Q')scanf("%d",&a),printf("%d\n",kth(a));
}
}
此为已经“优化”后的,除了快读快写与上面一样,但是全WA:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 100005
//快读
#ifdef ONLINE_JUDGE
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
#endif
template<typename T>inline void read(T& ret) {
ret=0;T f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
ret*=f;
}
template <typename T,typename... Args> inline void read(T& t, Args&... args)
{
read(t);read(args...);
}
//快写
char buffer[1<<21];
int p11=-1;
const int p22=(1<<21)-1;
inline void flush(){
fwrite(buffer,1,p11+1,stdout),p11=-1;
}
inline void putc(const char &x){
if (p11==p22)flush();
buffer[++p11]=x;
}
template<typename T>inline void write(T x){
static char buf[15];
static T len=-1;
if (x>=0){
do{
buf[++len]=x%10+48,x/=10;
}while(x);
} else{
putc('-');
do{
buf[++len]=-(x%10)+48,x/=10;
}while(x);
}
while(len>=0){
putc(buf[len]),--len;
}
}
template<typename T>inline void wrti(T x){
write(x),putc('\n');
}
int n,m,minn=1,maxn;
int root,vl[N],w[N],siz[N],lr[N][2];
int neww(int val,int x){
vl[x]=val;
w[x]=rand();
siz[x]=1;
return x;
}
void pushup(int p){siz[p]=siz[lr[p][0]]+siz[lr[p][1]]+1;}
void split(int p,int val,int &x,int &y){
if(!p){x=y=0;return;}
if(vl[p]<=val)x=p,split(lr[p][1],val,lr[p][1],y);
else y=p,split(lr[p][0],val,x,lr[p][0]);
pushup(p);
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(w[x]<w[y]){
lr[x][1]=merge(lr[x][1],y);
pushup(x);
return x;
}
else{
lr[y][0]=merge(x,lr[y][0]);
pushup(y);
return y;}
}
void insert(int &root,int val,int X){
int x,y;
split(root,val,x,y);
root=merge(merge(x,neww(val,X)),y);
}
void change(int val,int newval){
int x,y,z;
split(root,val,x,y);
split(x,val-1,x,z);
vl[z]=newval;
if(newval==minn)root=merge(merge(z,x),y);
else root=merge(merge(x,y),z);
}
int pre(int val){
int x,y,p;
split(root,val-1,x,y);p=x;
while(lr[p][1]) p=lr[p][1];
root=merge(x,y);
return p;
}
int last(int val){
int x,y,p;
split(root,val,x,y);
p=y;
while(lr[p][0]) p=lr[p][0];
root=merge(x,y);
return p;
}
void swp(int x,int y){
swap(vl[x],vl[y]);
swap(w[x],w[y]);
swap(siz[x],siz[y]);
swap(lr[x][0],lr[y][0]);
swap(lr[x][1],lr[y][1]);
}
void b_insert(int k,int val)
{
if(!val) return;
int t,x,y,z,a;
if(val<0){
t=pre(vl[k]);
split(root,vl[t],x,y);
split(x,vl[t]-1,x,z);
split(y,vl[k],y,a);
swp(y,z);
root=merge(x,merge(y,merge(z,a)));
}
else{
t=last(vl[k]);
split(root,vl[k],x,y);
split(x,vl[k]-1,x,z);
split(y,vl[t],y,a);
swp(y,z);
root=merge(x,merge(y,merge(z,a)));
}
}
int rnk(int val){
int x,y,res;
split(root,val-1,x,y);res=siz[x]+1;
root=merge(x,y);
return res;
}
int kth(int k){
int p=root;
while(1)
if(k<=siz[lr[p][0]]) p=lr[p][0];
else if(k==siz[lr[p][0]]+1)return p;
else k-=siz[lr[p][0]]+1,p=lr[p][1];
}
int main(){
srand(time(0));
char f[15];
int a;
read(n,m);
maxn=n;
for(int i=1;i<=n;++i){
read(a);
insert(root,i,a);
}
int b;
while(m--){
scanf("%s",f);
if(f[0]=='T')read(a),change(vl[a],--minn);
if(f[0]=='B')read(a),change(vl[a],++maxn);
if(f[0]=='I')read(a,b),b_insert(a,b);
if(f[0]=='A')read(a),wrti(rnk(vl[a])-1);
if(f[0]=='Q')read(a),wrti(kth(a));
}
flush();
return 0;
}
求大犇们指点!