Treap+莫队AC,但有一个疑问
查看原帖
Treap+莫队AC,但有一个疑问
117192
无产者万岁楼主2023/11/2 21:26
#include <bits/stdc++.h>
using namespace std;
struct Treap
{
	int lc,rc,siz,val,key;
}tree[300005];
struct node
{
	int l,r,k,id;
}q[50005];
int n,m,len,a[300005],pos[300005],ans[300005];
int root,idx;
bool cmp(node x,node y)
{
	if(pos[x.l]==pos[y.l])
		return x.r<y.r;
	return pos[x.l]<pos[y.l];
}
int new_node(int val)
{
	tree[++idx]={0,0,1,val,rand()};
	return idx;
}
void push_up(int id)
{
	tree[id].siz=tree[tree[id].lc].siz+tree[tree[id].rc].siz+1;
}
void zig(int &id)
{
	int p=tree[id].lc;
	tree[id].lc=tree[p].rc;
	tree[p].rc=id;
	tree[p].siz=tree[id].siz;
	push_up(id);
	id=p;
}
void zag(int &id)
{
	int p=tree[id].rc;
	tree[id].rc=tree[p].lc;
	tree[p].lc=id;
	tree[p].siz=tree[id].siz;
	push_up(id);
	id=p;
}
void Insert(int &id,int val)
{
	if(!id)
	{
		id=new_node(val);
		return;
	}
	tree[id].siz++;
	if(val<tree[id].val)
	{
		Insert(tree[id].lc,val);
		if(tree[tree[id].lc].key>tree[id].key)
			zig(id);
	}
	else
	{
		Insert(tree[id].rc,val);
		if(tree[tree[id].rc].key>tree[id].key)
			zag(id);
	}
}
void Erase(int &id,int val)
{
	if(!id)
		return;
	if(val<tree[id].val)
		Erase(tree[id].lc,val);
	else if(val>tree[id].val)
		Erase(tree[id].rc,val);
	else
	{
		if(!tree[id].lc||!tree[id].rc)
			id=tree[id].lc+tree[id].rc;
        //这里如果不直接return,会陷入死循环
		else if(tree[tree[id].lc].key>tree[tree[id].rc].key)
		{
			zig(id);
			Erase(tree[id].rc,val);
		}
		else
		{
			zag(id);
			Erase(tree[id].lc,val);
		}
	}
	push_up(id);
}
int QueryKth(int id,int rnk)
{
	if(tree[tree[id].lc].siz+1==rnk)
		return tree[id].val;
	else if(tree[tree[id].lc].siz>=rnk)
		return QueryKth(tree[id].lc,rnk);
	else
		return QueryKth(tree[id].rc,rnk-tree[tree[id].lc].siz-1);
}
int main()
{
	//ios::sync_with_stdio(0);
	//cin.tie(0);
	//cout.tie(0);
	srand(time(0));
	cin>>n>>m;
	len=sqrt(n);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		pos[i]=(i-1)/len+1;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>q[i].l>>q[i].r>>q[i].k;
		q[i].id=i;
	}
	sort(q+1,q+m+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++)
	{
		while(l>q[i].l)
			Insert(root,a[--l]);
		while(r<q[i].r)
			Insert(root,a[++r]);
		while(l<q[i].l)
			Erase(root,a[l++]);
		while(r>q[i].r)
			Erase(root,a[r--]);
		ans[q[i].id]=QueryKth(root,q[i].k);
	}
	for(int i=1;i<=m;i++)
		cout<<ans[i]<<"\n";
	return 0;
}

求教大佬,代码注释处,不return,平衡树板子题是可以过的啊,但此处却会陷入死循环,是什么原因呢?

2023/11/2 21:26
加载中...