FHQ Treap 96pts TLE 求调
查看原帖
FHQ Treap 96pts TLE 求调
1173109
OrientDragon楼主2025/7/30 17:55

取随机数的方法是在题解区找的,他也写的是 FHQ Treap。所以这个随机数应该能通过本题。

本代码是从弱化版改动而来的,核心部分可以通过弱化版题目

#include<bits/stdc++.h>
#define getchar() (p1==p2&&(p2=(p1=buffer)+fread(buffer,1,1<<21,stdin),p1==p2)?EOF:*p1++)
using namespace std;

const int N=1100005;

int n,m,opt,X,cnt,rt,x,y,z,lst,ret,seed=1;
char buffer[1<<21],*p1,*p2;

struct FHQ_Treap{
	int l,r,val,key,siz;
	FHQ_Treap(){
		l=r=val=key=siz=0;
	}
}fhq[N];

int rnd(){
	return seed*=19260817;
}

int read(){
	int x=0;
	char ch=getchar();
	while(ch<48||ch>57)ch=getchar();
	while(ch>=48&&ch<=57){
		x=x*10+(ch^48);
		ch=getchar();
	}
	return x;
}

void newnode(int v){
	fhq[++cnt].val=v;
	fhq[cnt].key=rnd();
	fhq[cnt].siz=1;
}

void upd(int x){
	fhq[x].siz=fhq[ fhq[x].l ].siz+fhq[ fhq[x].r ].siz+1;
}

void split(int rt,int val,int&x,int&y){
	if(!rt)return x=y=0,void();
	if(fhq[rt].val<=val)
		split(fhq[x=rt].r,val,fhq[rt].r,y);
	else split(fhq[y=rt].l,val,x,fhq[rt].l);
	if(x)upd(x);
	if(y)upd(y);
}

int merge(int x,int y){
	if(!x||!y)return x+y;
	if(fhq[x].key>fhq[y].key){
		fhq[x].r=merge(fhq[x].r,y);
		upd(x);
		return x;
	}
	fhq[y].l=merge(x,fhq[y].l);
	upd(y);
	return y;
}

void ins(int val){
	newnode(val);
	if(!rt)return rt=1,void();
	split(rt,val,x,y);
	rt=merge(merge(x,cnt),y);
}

void del(int val){
	split(rt,val,x,z);
	split(x,val-1,x,y);
	y=merge(fhq[y].l,fhq[y].r);
	rt=merge(merge(x,y),z);
}

int getrank(int val){
	split(rt,val-1,x,y);
	int ret=fhq[x].siz+1;
	rt=merge(x,y);
	return ret;
}

int getnum(int rank){
	int now=rt;
	while(now){
		if(fhq[ fhq[now].l ].siz+1==rank)
			return fhq[now].val;
		if(fhq[ fhq[now].l ].siz>=rank)
			now=fhq[now].l;
		else{
			rank-=fhq[ fhq[now].l ].siz+1;
			now=fhq[now].r;
		}
	}
}

int pre(int val){
	split(rt,val-1,x,y);
	int now=x;
	while(fhq[now].r)
		now=fhq[now].r;
	int ret=fhq[now].val;
	rt=merge(x,y);	
	return ret;
}

int nxt(int val){
	split(rt,val,x,y);
	int now=y;
	while(fhq[now].l)
		now=fhq[now].l;
	int ret=fhq[now].val;
	rt=merge(x,y);
	return ret;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		ins(read());
	while(m--){
		opt=read(),X=read();
		X^=lst;
		switch(opt){
			case 1:
				ins(X);
				break;
			case 2:
				del(X);
				break;
			case 3:
				ret^=(lst=getrank(X));
				break;
			case 4:
				ret^=(lst=getnum(X));
				break;
			case 5:
				ret^=(lst=pre(X));
				break;
			case 6:
				ret^=(lst=nxt(X));
				break;
		}
	}
	cout<<ret;
}
2025/7/30 17:55
加载中...