关于两份代码的差别
查看原帖
关于两份代码的差别
557385
cjlak1o1楼主2022/7/27 12:23

平衡树模板题,写了两份代码,几乎一样,一份52分,一份AC,求差别

//FHQ treap 52分
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1e3;

template<class T> T read(T &x){
	char c=getchar();bool f=0;x=0;
	while(!isdigit(c)) f|=c=='-',c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?-x:x;
}

int n,root;
struct TREE{
	int l,r,val,siz;
}t[N];
struct FHQ{
	int tot,pri[N];//x为A树根,y为B树根
	int build(int k){
		t[++tot].val=k,t[tot].siz=1,pri[tot]=rand();
		return tot;
	}
	void push_up(int rt){
		t[rt].siz=t[t[rt].l].siz+t[t[rt].r].siz+1;
	}
	void split(int rt,int k,int &x,int &y){
		if(!rt) x=y=0;//没有了,则返回
		else{
			if(t[rt].val<=k) x=rt,split(t[rt].r,k,t[rt].r,y);
			else y=rt,split(t[rt].l,k,x,t[rt].l);
			push_up(rt);
		}
	}
	int merge(int x,int y){
		if(!x||!y) return x+y;
		if(pri[x]<pri[y]){//A树并到B树左子树
			t[x].r=merge(t[x].r,y);
			push_up(x);return x;
		}else{//B树并到A树右子树
			t[y].l=merge(x,t[y].l);
			push_up(y);return y;
		}
	}
	int kth(int rt,int k){
		while(1){
			if(k<=t[t[rt].l].siz) rt=t[rt].l;
			else if(k==t[t[rt].l].siz+1) return rt;
			else k-=t[t[rt].l].siz+1,rt=t[rt].r;
		}
	}
	void insert(int k){
		int x,y;
		split(root,k,x,y);
		root=merge(merge(x,build(k)),y);
	}
	void del(int k){
		int x,y,z;
		split(root,k,x,z);
		split(x,k-1,x,y);
		y=merge(t[y].l,t[y].r);
		root=merge(merge(x,y),z);
	}
	int ran(int k){
		int x,y;
		split(root,k-1,x,y);
		int ans=t[x].siz+1;
		root=merge(x,y);
		return ans;
	}
	int from(int k){
		int x,y;
		split(root,k-1,x,y);
		int ans=t[kth(x,t[x].siz)].val;
		root=merge(x,y);
		return ans;
	}
	int nxt(int k){
		int x,y;
		split(root,k,x,y);
		int ans=t[kth(y,1)].val;
		root=merge(x,y);
		return ans;
	}
}fhq;

signed main(){
	srand(time(0));//rand()
	read(n);
	for(int i=1,opt,x;i<=n;i++){
		read(opt),read(x);
		switch(opt){
			case 1: fhq.insert(x);break;
			case 2: fhq.del(x);break;
			case 3: printf("%lld\n",fhq.ran(x));break;
			case 4: printf("%lld\n",t[fhq.kth(root,x)].val);break;
			case 5: printf("%lld\n",fhq.from(x));break;
			case 6: printf("%lld\n",fhq.nxt(x));break;
		}
	}
	return 0;
}
/*
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
*/
/*
106465
84185
492737
*/
2022/7/27 12:23
加载中...