非旋fhp-treap 洛谷IDE和本地跑的不一样
查看原帖
非旋fhp-treap 洛谷IDE和本地跑的不一样
227728
冰糖鸽子「僕は…」楼主2020/11/29 09:24

RT,对了1和11两个点,第2个点下下来在本地是对的,上洛谷IDE一个询问错了

2.in

20
1 964673
5 968705
4 1
3 964673
5 965257
1 915269
1 53283
3 964673
3 53283
3 53283
1 162641
5 973984
1 948119
2 915269
2 53283
6 959161
1 531821
1 967521
2 531821
1 343410

2.out

964673
964673
1
964673
3
1
1
964673
964673

洛谷IDE.out

964673
964673
1
964673
4 // 这里应该是3
1
1
964673
964673

代码:


// Problem: P3369 【模板】普通平衡树
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3369#sub
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
#define M 500005
int root,cnt,q,Q,x;
int rd[M],v[M],siz[M],son[M][3];
void p(int x)
{
	siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;
}
void split(int i,int k,int &l,int &r)//分成<=k的和>k的
{
	if(!i){l=r=0;return;}
	if(v[i]>k)
	{
		r=i;
		split(son[i][0],k,l,son[i][0]);
	}
	else
	{
		l=i; 
		split(son[i][1],k,son[i][1],r);
	}
}
int merge(int x,int y)
{
	if(!x||!y){return x+y;}
	if(rd[x]<rd[y])
	{
		son[x][1]=merge(son[x][1],y);
		p(x);return x;
	}
	else
	{
		son[y][0]=merge(x,son[y][0]);
		p(y);return y;
	}
}
void ins(int k)
{
	int fa,fb,fc;
	split(root,k,fa,fb);//k-1||k ?
	cnt++;
	siz[cnt]=1;
	v[cnt]=k;
	rd[cnt]=rand();
	root=merge(merge(fa,cnt),fb);
	p(cnt);
}
void del(int k)
{
	int fa,fb,fc;
	split(root,k,fa,fb);//fa<=k fb>k
	split(fa,k-1,fa,fc);//fa<=k-1 fa<k fc=k
	//最后 fb>k fa<k fc=k(不用fc)
	fc=merge(son[fc][0],son[fc][1]);
	root=merge(merge(fa,fc),fb);
}
void f_3(int k)
{
	int fa,fb,fc;
	split(root,k-1,fa,fb);//fa<k fb>=k
	cout<<siz[fa]+1<<fa<<v[fa]<<endl;
	root=merge(fa,fb);
}
void f_4(int k)
{
	int i=root;
	while(1)
	{
		if(k==siz[son[i][0]]+1){cout<<v[i]<<endl;return;}
		if(siz[son[i][0]]>=k){i=son[i][0];}
		else{k-=siz[son[i][0]]+1;i=son[i][1];}
	}
}
void f_5(int k)
{
	int fa,fb,fc;
	split(root,k-1,fa,fb);//fa<k fb>=k
	fc=fa;
	while(son[fc][1])
	{
		fc=son[fc][1];
	}
	cout<<v[fc]<<endl;
	root=merge(fa,fb);
}
void f_6(int k)
{
	int fa,fb,fc;
	split(root,k,fa,fb);//fa<=k fb>k 从fb里找最小
	fc=fb;
	while(son[fc][0])
	{
		fc=son[fc][0];
	}
	cout<<v[fc]<<endl;
	root=merge(fa,fb);
}
int main()
{
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		cin>>Q>>x;
		if(Q==1){ins(x);}
		if(Q==2){del(x);}
		if(Q==3){f_3(x);}
		if(Q==4){f_4(x);}
		if(Q==5){f_5(x);}
		if(Q==6){f_6(x);}
	}
	return 0;
}
2020/11/29 09:24
加载中...