求助线段树+Splay
查看原帖
求助线段树+Splay
723198
AAA404楼主2023/8/27 17:20

蒟蒻调不动了......

调了几小时才不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;
}
2023/8/27 17:20
加载中...