此题不让用超级快读快写吗
查看原帖
此题不让用超级快读快写吗
426545
light_ght楼主2021/7/19 09:50

此为未经优化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;
}

求大犇们指点!

2021/7/19 09:50
加载中...