社区讨论

求助,改两天了

P3380【模板】树套树参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo7uyrwp
此快照首次捕获于
2023/10/27 08:11
2 年前
此快照最后确认于
2023/10/27 08:11
2 年前
查看原帖
CPP
#include<iostream>
#include<cstring>
#define inf 2147483647
#define T tr[now]
#define FOR(i,x,y) for(int i(x);i<=y;++i)
using namespace std;
int a[50010];
struct node
{
	int ls,rs;
	int rnd;
	int siz;
	int val;
} tr[10000010];
int n,m;
int cnt;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline int read()
{
    char c=getchar();int x=0;bool f=0;
    for(;!isdigit(c);c=getchar())f^=!(c^45);
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
    if(f)x=-x;return x;
}
int x,y,z;
struct treap
{
	int rt;
	inline void pushup(int now)
	{
		T.siz=tr[T.ls].siz+tr[T.rs].siz+1;
		return;
	}
	inline void split(int now,int k,int &x,int &y)
	{
		if(!now)x=y=0;
		else
		{
			if(T.val<=k)x=now,split(T.rs,k,tr[x].rs,y);
			else y=now,split(T.ls,k,x,tr[y].ls);
			pushup(now);
		}
		return;
	}
	inline int merge(int A,int B)
	{
		if(!A||!B)return A+B;
		else if(tr[A].rnd<tr[B].rnd)
		{
			tr[A].rs=merge(tr[A].rs,B);
			pushup(A);
			return A;
		}
		else
		{
			tr[B].ls=merge(A,tr[B].ls);
			pushup(B);
			return B;
		}
	}
	inline int add(int now)
	{
		tr[++cnt].val=now;
		tr[cnt].rnd=rand();
		tr[cnt].siz=1;
		return cnt;
	}
	inline void ins(int now)
	{
		int x,y;
		split(rt,now,x,y);
		rt=merge(merge(x,add(now)),y);
		return;
	}
	inline void del(int now)
	{
		split(rt,now,x,z);
		split(x,now-1,x,y);
		y=merge(tr[y].ls,tr[y].rs);
		rt=merge(merge(x,y),z);
		return;
	}
	inline int rk(int now)
	{
		split(rt,now-1,x,y);
		int res=tr[x].siz+1;
		rt=merge(x,y);
		return res;
	}
	inline int kth(int now,int k)
	{
		while(1)
		{
			if(!tr[now].siz)return 0;
			else if(k<=tr[tr[now].ls].siz)
				now=tr[now].ls;
			else if(k==tr[tr[now].ls].siz+1)return tr[now].val;
			else
			{
				k-=tr[tr[now].ls].siz+1;
				now=tr[now].rs;
			}
		}
	}
	inline int pre(int now)
	{
		split(rt,now,x,y);
		int res=kth(x,tr[x].siz);
		if(!tr[x].siz)res=-inf;
		rt=merge(x,y);
		return res;
	}
	inline int nxt(int now)
	{
		split(rt,now-1,x,y);
		int res=kth(y,1);
		if(!tr[y].siz)res=inf;
		rt=merge(x,y);
		return res;
	}
	inline void build(int l, int r)
	{
		FOR(i,l,r)ins(a[i]);
		return;
	}
} ft[200001];
struct segmentree
{
	inline void build(int x,int l,int r)
	{
		ft[x].build(l,r);
		if(l==r)return;
		int mid=l+r>>1;
		build(x<<1,l,mid);
		build(x<<1|1,mid+1,r);
	}
	inline int getrank(int x,int L,int R,int l,int r,int k)
	{
		if (R<l||L>r)return 0;
		if (l<=L&&R<=r)return ft[x].rk(k)-1;
		int mid=L+R>>1;
		return getrank(x<<1,L,mid,l,r,k)+getrank(x<<1|1,mid+1,R,l,r,k);
	}
	inline int getk(int l,int r,int k)
	{
		int L=0,R=inf,ans=-1;
		int mid;
		while(L<=R)
		{
			mid=L+R>>1;
			if(getrank(1,1,n,l,r,mid)+1<=k)ans=mid,L=mid+1;
			else R=mid-1;
		}
		return ans;
	}

	inline void update(int x,int L,int R,int p,int k)
	{
		ft[x].del(a[p]);
		ft[x].ins(k);
		if(L==R)return;
		int mid=L+R>>1;
		if(p<=mid) update(x<<1,L,mid,p,k);
		else update(x<<1|1,mid+1,R,p,k);
	}

	inline int getpre(int x,int L,int R,int l,int r,int k)
	{
		if (R<l||L>r)return -inf;
		if (l<=L&&R<=r)return ft[x].pre(k);
		int mid=L+R>>1;
		return max(getpre(x<<1,L,mid,l,r,k),getpre(x<<1|1,mid+1,R,l,r,k));
	}
	inline int getnxt(int x,int L,int R,int l,int r,int k)
	{
		if (R<l||L>r)return inf;
		if (l<=L&&R<=r)return ft[x].nxt(k);
		int mid=L+R>>1;
		return min(getnxt(x<<1,L,mid,l,r,k),getnxt(x<<1|1,mid+1,R,l,r,k));
	}
} ST;
int main()
{
	//freopen("tree.in","r",stdin);
	//freopen("std.out","w",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	srand(6666666);
	n=read(),m=read();
	FOR(i,1,n)a[i]=read();
	ST.build(1,1,n);
	int l,r,k,p;
	FOR(i,1,m)
	{
		int opt;
		opt=read();
		if(opt==1)
		{
			l=read(),r=read(),k=read();
			cout<<ST.getrank(1,1,n,l,r,k)+1<<endl;
		}
		else if(opt==2)
		{
			l=read(),r=read(),k=read();
			cout<<ST.getk(l,r,k)<<endl;
		}
		else if(opt==3)
		{
			p=read(),k=read();
			ST.update(1,1,n,p,k);
		}
		else if(opt==4)
		{
			l=read(),r=read(),k=read();
			cout<<ST.getpre(1,1,n,l,r,k)<<endl;
		}
		else
		{
			l=read(),r=read(),k=read();
			cout<<ST.getnxt(1,1,n,l,r,k)<<endl;
		}
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...