学了一下主席树,由于怕调不出来,选择了用普通线段树套权值线段树。
犯得一些傻逼错误是:
①把大小写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);
}