FHQ Treap 80pts TLE求卡常
查看原帖
FHQ Treap 80pts TLE求卡常
642173
KarmaticEnding楼主2024/12/11 12:33

已经试过把 get_nextget_prev 改成递归了,没用

#include<cstdio>
#include<random>
using namespace std;
const int MAXN=5e5+10;
mt19937 rnd(114514);
int a[MAXN];
int n,m;
inline int max(int H,int G){
	return H>G?H:G;
}
inline int min(int H,int G){
	return H<G?H:G;
}
struct TREAP{
	struct TREENODE{
		int lson;
		int rson;
		int size_subtree;
		int dat,val;
		TREENODE(){
			lson=rson=0;
		}
	}tr[MAXN<<5];
	#define ls(u) tr[u].lson
	#define rs(u) tr[u].rson
	int tot=0;
	void New(int val){
		tr[++tot].val=val;
		tr[tot].dat=rnd();
		tr[tot].size_subtree=1;
	}
	inline void pushup(int &u){
		tr[u].size_subtree=tr[ls(u)].size_subtree+tr[rs(u)].size_subtree+1;
	}
	void Split(int u,int val,int &L,int &R){
		if(u==0){
			L=R=0;
			return;
		}
		if(tr[u].val<=val){
			L=u;
			Split(rs(L),val,rs(L),R);
		}
		else{
			R=u;
			Split(ls(R),val,L,ls(R));
		}
		pushup(u);
	}
	int Merge(int L,int R){
		if(L==0||R==0){
			return L|R;
		}
		if(tr[L].dat>tr[R].dat){
			rs(L)=Merge(rs(L),R);
			pushup(L);
			return L;
		}
		else{
			ls(R)=Merge(L,ls(R));
			pushup(R);
			return R;
		}
	}
	void Insert(int &rot,int val){
		int L,R;
		Split(rot,val,L,R);
		New(val);
		rot=Merge(Merge(L,tot),R);
	}
	void Delete(int &rot,int val){
		int L,R,p;
		Split(rot,val,L,R);
		Split(L,val-1,L,p);
		p=Merge(ls(p),rs(p));
		rot=Merge(Merge(L,p),R);
	}
	int get_rank(int &rot,int val){
		int L,R;
		Split(rot,val-1,L,R);
		int res=tr[L].size_subtree-1;
		rot=Merge(L,R);
		return res;	
	}
	int get_value(int u,int rk){
		if(rk==tr[ls(u)].size_subtree+1){
			return u;
		}
		else if(rk>tr[ls(u)].size_subtree+1){
			return get_value(rs(u),rk-tr[ls(u)].size_subtree-1);
		}
		else{
			return get_value(ls(u),rk);
		}
	}
	int get_prev(int &rot,int val){
		int L,R;
		Split(rot,val-1,L,R);
		int res=tr[get_value(L,tr[L].size_subtree)].val;
		rot=Merge(L,R);
		return res;
	}
	int get_next(int &rot,int val){
		int L,R;
		Split(rot,val,L,R);
		int res=tr[get_value(R,1)].val;
		rot=Merge(L,R);
		return res;
	}
	#undef ls
	#undef rs
}Treap;
struct SegmentTree{
	int root[MAXN<<2];
	#define ls rt<<1
	#define rs (rt<<1)|1
	#define lson l,mid,rt<<1
	#define rson mid+1,r,(rt<<1)|1
	void build(int l,int r,int rt){
		Treap.Insert(root[rt],-2147483647);
		for(int i=l;i<=r;++i){
			Treap.Insert(root[rt],a[i]);
		}
		Treap.Insert(root[rt],2147483647);
		if(l==r){
			return;
		}
		int mid=(l+r)>>1;
		build(lson);
		build(rson);
	}
	void update(int pos,int val,int l,int r,int rt){
		Treap.Delete(root[rt],a[pos]);
		Treap.Insert(root[rt],val);
		if(l==r){
			return;
		}
		int mid=(l+r)>>1;
		if(pos<=mid){
			update(pos,val,lson);
		}
		else{
			update(pos,val,rson);
		}
	}
	int get_rank(int L,int R,int val,int l,int r,int rt){
		if(L<=l&&r<=R){
			return Treap.get_rank(root[rt],val);
		}
		int mid=(l+r)>>1;
		if(R<=mid){
			return get_rank(L,R,val,lson);
		}
		if(L>mid){
			return get_rank(L,R,val,rson);
		}
		return get_rank(L,R,val,lson)+get_rank(L,R,val,rson);
	}
	int get_value(int L,int R,int rk){
		int l=0,r=1e8;
		while(l<r){
			int mid=(l+r+1)>>1;
			if(get_rank(L,R,mid,1,n,1)<rk){
				l=mid;
			}
			else{
				r=mid-1;
			}
		}
		return r;
	}
	int get_prev(int L,int R,int val,int l,int r,int rt){
		if(l>R||r<L){
			return -2147483647;
		}
		else if(L<=l&&r<=R){
			return Treap.get_prev(root[rt],val);
		}
		else{
			int mid=(l+r)>>1;
			return max(get_prev(L,R,val,lson),get_prev(L,R,val,rson));
		}
	}
	int get_next(int L,int R,int val,int l,int r,int rt){
		if(l>R||r<L){
			return 2147483647;
		}
		else if(L<=l&&r<=R){
			return Treap.get_next(root[rt],val);
		}
		else{
			int mid=(l+r)>>1;
			return min(get_next(L,R,val,lson),get_next(L,R,val,rson));
		}
	}
	#undef ls
	#undef rs
	#undef lson
	#undef rson
}T;
char *p1,*p2,buf[MAXN];
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++)
inline void read(int &x){
	char c;
	c=gc();
	while(c<'0'||c>'9'){
		c=gc();
	}
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+(c&15);
		c=gc();
	}
}
int main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
	}
	T.build(1,n,1);
	for(int kkk=1,op,x,y,k;kkk<=m;++kkk){
		scanf("%d%d%d",&op,&x,&y);
		if(op==3){
			T.update(x,y,1,n,1);
			a[x]=y;
		}
		else{
			scanf("%d",&k);
			switch(op){
				case 1:{
					printf("%d\n",T.get_rank(x,y,k,1,n,1)+1);
					break;
				}
				case 2:{
					printf("%d\n",T.get_value(x,y,k));
					break;
				}
				case 4:{
					printf("%d\n",T.get_prev(x,y,k,1,n,1));
					break;
				}
				case 5:{
					printf("%d\n",T.get_next(x,y,k,1,n,1));
					break;
				}
			}
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
2024/12/11 12:33
加载中...