蒟蒻调不动了......
调了几小时才不RE,现在样例还过不了,求大佬纠错:到底是平衡树挂了还是线段树挂了
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5,INF=2147483647;
int n,m,l,r,k,op,pos,a[N],cnt;
struct Node{
int ch[2],fa,val,sz;
};
struct Splay{
Node spl[N];
#define ls(x) spl[x].ch[0]
#define rs(x) spl[x].ch[1]
#define fa(x) spl[x].fa
#define val(x) spl[x].val
#define sz(x) spl[x].sz
#define ident(x,f) (rs(f)==x)
#define connect(x,f,s) (spl[fa(x)=f].ch[s]=x)
#define update(x) sz(x)=sz(ls(x))+sz(rs(x))
inline void rotate(int x)
{
int f=fa(x),ff=fa(f),k=ident(x,f);
connect(spl[x].ch[k^1],f,k);
connect(x,ff,ident(f,ff));
connect(f,x,k^1);
update(f),update(x);
return;
}
inline void splaying(int &rt,int x,int top)
{
if(!top)rt=x;
while(fa(x)!=top)
{
int f=fa(x),ff=fa(f);
if(ff!=top)ident(x,f)^ident(f,ff)?rotate(x):rotate(f);
rotate(x);
}
return;
}
inline void newnode(int &now,int val,int fa=0)
{
val(now=++cnt)=val;
fa(now)=fa;
sz(now)=1;
return;
}
inline void ins(int &rt,int val)
{
if(!rt)
{
newnode(rt,val);
return;
}
int x=rt,f=0;
while(1)
{
f=x;
x=spl[x].ch[spl[x].val<val];
if(!x)
{
spl[++cnt].val=val;
spl[cnt].sz=1;
spl[cnt].fa=f;
spl[f].ch[spl[f].val<val]=cnt;
update(cnt);
update(f);
splaying(rt,cnt,0);
return;
}
}
}
inline void delnode(int &rt,int x)
{
splaying(rt,x,0);
if(rs(x))
{
int p=rs(x);
while(ls(p))p=ls(p);
splaying(rt,p,x);
connect(ls(x),p,0);
rt=p;
fa(p)=0;
update(rt);
}
else rt=ls(x),fa(rt)=0;
return;
}
inline void del(int &rt,int now,int val)
{
if(val==val(now))delnode(rt,now);
else if(val<val(now))del(rt,ls(now),val);
else del(rt,rs(now),val);
return;
}
inline int pre(int rt)
{
int now=ls(rt);
while(rs(now))now=rs(now);
return now;
}
inline int nxt(int rt)
{
int now=rs(rt);
while(ls(now))now=ls(now);
return now;
}
#undef ls
#undef rs
}sp;
struct node{
int l,r,rt,maxx,minn;
};
struct Tree{
node Tr[N<<2];
#define ls(x) x<<1
#define rs(x) x<<1|1
inline void pushup(int id)
{
Tr[id].maxx=max(Tr[ls(id)].maxx,Tr[rs(id)].maxx);
Tr[id].minn=min(Tr[ls(id)].minn,Tr[rs(id)].minn);
return;
}
inline void build(int id,int l,int r)
{
Tr[id]={l,r};
sp.ins(Tr[id].rt,-INF);
sp.ins(Tr[id].rt,INF);
for(int i=l;i<=r;i++)
sp.ins(Tr[id].rt,a[i]);
if(l==r)
{
Tr[id].maxx=Tr[id].minn=a[l];
return;
}
int mid=l+r>>1;
build(ls(id),l,mid);
build(rs(id),mid+1,r);
pushup(id);
return;
}
inline int query_max(int id,int a,int b)
{
int l=Tr[id].l,r=Tr[id].r;
if(a<=l&&r<=b)
{
return Tr[id].maxx;
}
int mid=l+r>>1,ans=-INF;
if(a<=mid)ans=max(ans,query_max(ls(id),a,b));
if(b>mid)ans=max(ans,query_max(rs(id),a,b));
return ans;
}
inline int query_min(int id,int a,int b)
{
int l=Tr[id].l,r=Tr[id].r;
if(a<=l&&r<=b)
{
return Tr[id].minn;
}
int mid=l+r>>1,ans=INF;
if(a<=mid)ans=min(ans,query_min(ls(id),a,b));
if(b>mid)ans=min(ans,query_min(rs(id),a,b));
return ans;
}
inline int query_order(int id,int a,int b,int val)
{
int l=Tr[id].l,r=Tr[id].r;
if(a<=l&&r<=b)
{
sp.ins(Tr[id].rt,val);
int ans=sp.spl[sp.spl[Tr[id].rt].ch[0]].sz-1;
sp.del(Tr[id].rt,Tr[id].rt,val);
return ans;
}
int mid=l+r>>1,ans=0;
if(a<=mid)ans+=query_order(ls(id),a,b,val);
if(b>mid)ans+=query_order(rs(id),a,b,val);
return ans;
}
inline int query_number(int a,int b,int val)
{
int l=1,r=query_max(1,a,b),mid,tmp;
while(l<r)
{
mid=l+r+1>>1;
tmp=query_order(1,a,b,mid);
if(tmp<val)
l=mid;
else
r=mid-1;
}
return l;
}
inline void modify(int id,int p,int val)
{
sp.del(Tr[id].rt,Tr[id].rt,a[p]);
sp.ins(Tr[id].rt,val);
int l=Tr[id].l,r=Tr[id].r;
if(l==r)
{
Tr[id].maxx=Tr[id].minn=val;
a[p]=val;
return;
}
int mid=l+r>>1;
if(p<=mid)modify(ls(id),p,val);
else modify(rs(id),p,val);
pushup(id);
return;
}
inline int query_pre(int id,int a,int b,int val)
{
int l=Tr[id].l,r=Tr[id].r;
if(a<=l&&r<=b)
{
sp.ins(Tr[id].rt,val);
int ans=sp.spl[sp.pre(Tr[id].rt)].val;
sp.del(Tr[id].rt,Tr[id].rt,val);
return ans;
}
int mid=l+r>>1,ans=-INF;
if(a<=mid)ans=max(ans,query_pre(ls(id),a,b,val));
if(b>mid)ans=max(ans,query_pre(rs(id),a,b,val));
return ans;
}
inline int query_nxt(int id,int a,int b,int val)
{
int l=Tr[id].l,r=Tr[id].r;
if(a<=l&&r<=b)
{
sp.ins(Tr[id].rt,val);
int ans=sp.spl[sp.nxt(Tr[id].rt)].val;
sp.del(Tr[id].rt,Tr[id].rt,val);
return ans;
}
int mid=l+r>>1,ans=INF;
if(a<=mid)ans=min(ans,query_nxt(ls(id),a,b,val));
if(b>mid)ans=max(ans,query_nxt(rs(id),a,b,val));
return ans;
}
}T;
int main()
{
clock_t c1=clock();
#ifdef LOCAL
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
T.build(1,1,n);
while(m--)
{
cin>>op;
switch(op)
{
case 1:
cin>>l>>r>>k;
cout<<T.query_order(1,l,r,k)<<endl;
break;
case 2:
cin>>l>>r>>k;
cout<<T.query_number(l,r,k)<<endl;
break;
case 3:
cin>>pos>>k;
T.modify(1,pos,k);
break;
case 4:
cin>>l>>r>>k;
cout<<T.query_pre(1,l,r,k)<<endl;
break;
case 5:
cin>>l>>r>>k;
cout<<T.query_nxt(1,l,r,k)<<endl;
break;
}
}
#ifdef LOCAL
cerr<<"Time used:"<<clock()-c1<<"ms";
#endif
return 0;
}