学了一下主席树,由于怕调不出来,选择了用普通线段树套权值线段树。
犯得一些傻逼错误是:
①把大小写n混用结果弄错了。
②没过样例TM就交了。
③被题意坑了,“保证有序序列所有值在任何时刻满足[0,10^8]",并不意味着询问非负。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #include<iostream> char * p=(char *)malloc(5000000); inline int in(){ int x=0; bool flag=0; while(*p<'0'||*p>'9')flag|=*p++=='-'; while(*p>='0'&&*p<='9')x=x*10+*p++-'0'; return flag?-x:x; } char buf[500000],* ptr=buf,tmp[10]; inline void out(int x){ int tot=0; for(;x;x/=10)tmp[tot++]=x%10+'0'; if(tot==0)*ptr++='0'; else while(tot--)*ptr++=tmp[tot]; *ptr++='\n'; } int seq[50001],a[100001],N; struct TS{ int size,max,min; TS * c[2]; }root[200000],treepool[13000000],* list[40]; #define lson node<<1,l,(l+r)>>1 #define rson node<<1|1,((l+r)>>1)+1,r int treetop=1,listtop; int l[50000],r[50000],k[50000],opt[50000]; inline void add(TS * node,int l,int r,int A,int delta){ node->size+=delta; if(l!=r){ if(A>(l+r)>>1){ if(node->c[1]==treepool){ node->c[1]=treepool+treetop; treepool[treetop].c[0]=treepool[treetop].c[1]=treepool; treepool[treetop].max=-1,treepool[treetop].min=0x7fffffff; ++treetop; } add(node->c[1],((l+r)>>1)+1,r,A,delta); } else{ if(node->c[0]==treepool){ node->c[0]=treepool+treetop; treepool[treetop].c[0]=treepool[treetop].c[1]=treepool; treepool[treetop].max=-1,treepool[treetop].min=0x7fffffff; ++treetop; } add(node->c[0],l,(l+r)>>1,A,delta); } node->max=max(node->c[0]->max,node->c[1]->max); node->min=min(node->c[0]->min,node->c[1]->min); } else if(node->size)node->max=node->min=l; else node->max=-1,node->min=0x7fffffff; } inline int sum(TS * node,int l,int r,int A){ if(l>=A||node->size==0)return 0; if(r<A)return node->size; return sum(node->c[0],l,(l+r)>>1,A)+sum(node->c[1],((l+r)>>1)+1,r,A); } inline int qk(int k){ int suml,sumr,i,l=0,r=N-1; while(l!=r){ suml=0,sumr=0; for(i=listtop;i--;)suml+=list[i]->c[0]->size,sumr+=list[i]->c[1]->size; if(suml>=k){ for(i=listtop;i--;)list[i]=list[i]->c[0]; r=(l+r)>>1; } else{ for(i=listtop;i--;)list[i]=list[i]->c[1]; l=((l+r)>>1)+1; k-=suml; } } return l; } inline int pred(TS * node,int l,int r,int A){ if(l>=A||node->size==0)return -1; if(r<A)return node->max; return max(pred(node->c[0],l,(l+r)>>1,A),pred(node->c[1],((l+r)>>1)+1,r,A)); } inline int succ(TS * node,int l,int r,int A){ if(r<A||node->size==0)return 0x7fffffff; if(l>=A)return node->min; return min(succ(node->c[0],l,(l+r)>>1,A),succ(node->c[1],((l+r)>>1)+1,r,A)); } inline void build(int node,int l,int r){ if(l!=r)build(lson),build(rson); for(;l<=r;++l)add(root+node,0,N-1,seq[l],1); } inline int sum(int node,int l,int r,int L,int R,int A){ if(l>R||r<L)return 0; if(L<=l&&r<=R)return sum(root+node,0,N-1,A); return sum(lson,L,R,A)+sum(rson,L,R,A); } inline void get(int node,int l,int r,int L,int R){ if(L<=l&&r<=R){ list[listtop++]=root+node; return; } if(R>(l+r)>>1)get(rson,L,R); if(L<=(l+r)>>1)get(lson,L,R); } inline void del(int node,int l,int r,int A){ add(root+node,0,N-1,seq[A],-1); if(A>(l+r)>>1)del(rson,A); else if(l!=r)del(lson,A); } inline void add(int node,int l,int r,int A,int k){ add(root+node,0,N-1,k,1); if(A>(l+r)>>1)add(rson,A,k); else if(l!=r)add(lson,A,k); } inline int pred(int node,int l,int r,int L,int R,int A){ if(l>R||r<L)return -1; if(L<=l&&r<=R)return pred(root+node,0,N-1,A); return max(pred(lson,L,R,A),pred(rson,L,R,A)); } inline int succ(int node,int l,int r,int L,int R,int A){ if(l>R||r<L)return 0x7fffffff; if(L<=l&&r<=R)return succ(root+node,0,N-1,A); return min(succ(lson,L,R,A),succ(rson,L,R,A)); } int main(){ freopen("psh.in","r",stdin); freopen("psh.out","w",stdout); fread(p,1,5000000,stdin); int n=in(),m=in(),i,j; //Read,Sort,and Hash. for(i=1;i<=n;++i)seq[i]=in(),a[i-1]=seq[i]; N=n; for(i=0;i<m;++i){ opt[i]=in(),l[i]=in(); if(opt[i]!=3)r[i]=in(); k[i]=in(); if(opt[i]==3)a[N++]=k[i]; } sort(a,a+N); N=unique(a,a+N)-a; for(i=1;i<=n;++i)seq[i]=lower_bound(a,a+N,seq[i])-a; treepool->max=-1,treepool->min=0x7fffffff,treepool->c[0]=treepool->c[1]=treepool; for(i=0;i<200000;++i)root[i].max=-1,root[i].min=0x7fffffff,root[i].c[0]=root[i].c[1]=treepool; build(1,1,n); for(i=0;i<m;++i) switch(opt[i]){ case 1: k[i]=lower_bound(a,a+N,k[i])-a; if(k[i])out(sum(1,1,n,l[i],r[i],k[i])+1); else out(1); break; case 2: listtop=0; get(1,1,n,l[i],r[i]); out(a[qk(k[i])]); break; case 3: k[i]=lower_bound(a,a+N,k[i])-a; del(1,1,n,l[i]); add(1,1,n,l[i],k[i]); seq[l[i]]=k[i]; break; case 4: out(a[pred(1,1,n,l[i],r[i],lower_bound(a,a+N,k[i])-a)]);//<A break; case 5: out(a[succ(1,1,n,l[i],r[i],upper_bound(a,a+N,k[i])-a)]);//>=A break; } fwrite(buf,1,ptr-buf,stdout); }