本地测是对的,但到了在线IDE之后就超时,我加了一堆调试语句后发现在Splay.findx
这里超时了,求大佬看一下。
#include<bits/stdc++.h>
using namespace std;
namespace io {
inline int read() {
int __x=0,__f=1;
char __c=getchar();
while(__c<'0'||__c>'9') {
if(__c=='-')__f=-1;
__c=getchar();
}
while(__c>='0'&&__c<='9') {
__x=__x*10+__c-'0';
__c=getchar();
}
return __x*__f;
}
char __F[200];
inline void write(int __x) {
if(__x==0) {
putchar('0');
return;
}
int __tmp,__cnt=0;
if(__x>0) {
__tmp=__x;
} else {
__tmp=-__x;
}
if(__x<0) {
putchar('-');
}
while(__tmp>0) {
__F[__cnt++]=__tmp%10+'0';
__tmp/=10;
}
while(__cnt>0) {
putchar(__F[--__cnt]);
}
}
}
using namespace io;
const int maxn=100005;
int n,m,a[maxn];
struct splaytree {
int news,cnt;
struct tree {
int sum,f,num,siz,ln,rn;
int ch[2];
} t[maxn*20];
void pushup(int x) {
t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+t[x].num;
return;
}
void rotate(int x,int &rot) {
int y=t[x].f,z=t[y].f,L=(t[y].ch[0]!=x),R=L^1;
if(y==rot) {
rot=x;
} else {
t[z].ch[t[z].ch[0]!=y]=x;
}
t[x].f=z;
t[y].f=x;
t[t[x].ch[R]].f=y;
t[y].ch[L]=t[x].ch[R];
t[x].ch[R]=y;
pushup(y);
pushup(x);
}
void splay(int x,int &rot) {
while(x!=rot) {
int y=t[x].f,z=t[y].f;
if(y!=rot) {
if(t[y].ch[0]==x^t[z].ch[0]==y) {
rotate(x,rot);
} else {
rotate(y,rot);
}
}
rotate(x,rot);
}
}
int getfront(int rot) {
int x=t[rot].ch[0];
while(t[x].ch[1]) {
x=t[x].ch[1];
}
return x;
}
int getback(int rot) {
int x=t[rot].ch[1];
while(t[x].ch[0]) {
x=t[x].ch[0];
}
return x;
}
void insert(int rot,int x) {
if(t[rot].sum>x&&t[rot].ch[0]) {
insert(t[rot].ch[0],x);
} else if(t[rot].sum<x&&t[rot].ch[1]) {
insert(t[rot].ch[1],x);
} else if(t[rot].sum==x) {
t[rot].num++;
t[rot].siz++;
news=rot;
} else {
t[rot].ch[t[rot].sum<x]=++cnt;
t[cnt].f=rot;
t[cnt].siz=1;
t[cnt].num=1;
t[cnt].sum=x;
news=cnt;
}
pushup(rot);
}
void del(int &root,int rot,int x) {
if(t[rot].sum>x&&t[rot].ch[0]) {
del(root,t[rot].ch[0],x);
} else if(t[rot].sum<x&&t[rot].ch[1]) {
del(root,t[rot].ch[1],x);
} else if(t[rot].sum==x) {
t[rot].num--;
if(!t[rot].num) {
splay(rot,root);
int he=getfront(root),ta=getback(root);
splay(he,root);
splay(ta,t[he].ch[1]);
t[rot].f=t[rot].siz=t[rot].sum=t[ta].ch[0]=0;
pushup(ta);
pushup(he);
}
}
pushup(rot);
}
int findx(int &rot,int x) {
if(!rot)return 0;
int u=rot;
while(t[u].ch[(t[u].sum<x)]!=0&&t[u].sum!=x) {
cout<<'#'<<endl;
cout<<u<<' '<<(t[u].sum<x)<<' '<<t[u].ch[(t[u].sum<x)]<<' '<<t[u].sum<<' '<<t[t[u].ch[(t[u].sum<x)]].sum<<endl;
u=t[u].ch[(t[u].sum<x)];
cout<<u<<' '<<(t[u].sum<x)<<' '<<t[u].ch[(t[u].sum<x)]<<' '<<t[u].sum<<' '<<t[t[u].ch[(t[u].sum<x)]].sum<<endl;
}
cout<<'*';
splay(u,rot);
//cout<<'*';
return t[rot].sum>=x?t[t[rot].ch[0]].siz-1:t[t[rot].ch[0]].siz+t[rot].num-1;
}
int findk(int rot,int k) {
int lsiz=t[t[rot].ch[0]].siz;
if(!rot)return INT_MAX;
if(lsiz+t[rot].num>=k&&lsiz<k) {
return rot;
} else if(lsiz>=k) {
return findk(t[rot].ch[0],k);
} else {
return findk(t[rot].ch[1],k-lsiz-t[rot].num);
}
}
int get(int &rot,int x,int pd) {
insert(rot,x);
splay(news,rot);
int ans=t[pd?getfront(rot):getback(rot)].sum;
del(rot,rot,x);
return ans;
}
void tab(int &root) {
root=++cnt;
t[++cnt].f=cnt-1;
t[cnt-1].ch[0]=cnt;
t[cnt].sum=INT_MIN+1;
t[cnt-1].sum=INT_MAX;
t[cnt].num=t[cnt-1].num=1;
t[cnt].siz=1;
t[cnt-1].siz=2;
}
} Splay;
struct segment {
struct tree {
int l,r,root;
} t[maxn*8];
void build(int id,int l,int r) {
t[id].l=l;
t[id].r=r;
Splay.tab(t[id].root);
for(register int i=l; i<=r; i++) {
Splay.insert(t[id].root,a[i]);
}
if(l==r)return;
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
void change(int id,int x,int y) {
if(t[id].l>x||t[id].r<x)return;
Splay.del(t[id].root,t[id].root,a[x]);
Splay.insert(t[id].root,y);
Splay.splay(Splay.news,t[id].root);
if(t[id].l==t[id].r)return;
change(id*2,x,y);
change(id*2+1,x,y);
}
int qrank(int id,int l,int r,int k) {
if(t[id].l>r||t[id].r<l)return 0;
if(t[id].l>=l&&t[id].r<=r)return Splay.findx(t[id].root,k);
return qrank(id*2,l,r,k)+qrank(id*2+1,l,r,k);
}
int qnum(int u,int v,int k) {
int l=0,r=1e8,mid,ans;
while(l<=r) {
mid=(l+r)/2;
//cout<<l<<' '<<r<<' '<<mid<<endl;
if(qrank(1,u,v,mid)<k) {
l=mid+1;
ans=mid;
} else {
r=mid-1;
}
}
return ans;
}
int qfb(int id,int l,int r,int k,int pd) {
if(t[id].l>r||t[id].r<l)return pd?INT_MIN+1:INT_MAX;
if(t[id].l>=l&&t[id].r<=r) {
return Splay.get(t[id].root,k,pd);
}
int lc=qfb(id*2,l,r,k,pd),rc=qfb(id*2+1,l,r,k,pd);
return pd?max(lc,rc):min(lc,rc);
}
void dfscout(int id) {
cout<<t[id].l<<' '<<t[id].r<<' '<<t[id].root<<endl;
if(t[id].l==t[id].r) {
return;
}
dfscout(id*2);
dfscout(id*2+1);
}
} Seg;
int main() {
int x,y,z,w;
n=read(),m=read();
//scanf("%d%d",&n,&m);
for(register int i=1; i<=n; i++) {
a[i]=read();
//scanf("%d",&a[i]);
}
Seg.build(1,1,n);
// Seg.dfscout(1);
// puts("------");
// for(register int i=1; i<=Splay.cnt; i++) {
// cout<<Splay.t[i].sum<<' '<<Splay.t[i].f<<' '<<Splay.t[i].ch[0]<<' '<<Splay.t[i].ch[1]<<' '<<Splay.t[i].siz<<' '<<Splay.t[i].num<<endl;
// }
for(register int i=1; i<=m; i++) {
w=read(),x=read(),y=read();
//scanf("%d%d%d",&w,&x,&y);
//cout<<w<<' '<<x<<' '<<y<<endl;
switch(w) {
case 1: {
z=read();
//scanf("%d",&z);
write(Seg.qrank(1,x,y,z)+1);
putchar('\n');
break;
}
case 2: {
z=read();
//scanf("%d",&z);
write(Seg.qnum(x,y,z));
putchar('\n');
break;
}
case 3: {
Seg.change(1,x,y);
a[x]=y;
break;
}
case 4: {
z=read();
//scanf("%d",&z);
write(Seg.qfb(1,x,y,z,1));
putchar('\n');
break;
}
case 5: {
z=read();
//scanf("%d",&z);
write(Seg.qfb(1,x,y,z,0));
putchar('\n');
break;
}
}
}
return 0;
}