社区讨论

Why MLE

P11266【模板】可并堆 2参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhjaqmwp
此快照首次捕获于
2025/11/03 23:30
4 个月前
此快照最后确认于
2025/11/03 23:30
4 个月前
查看原帖
RT,我再次使用了 Treap 来试图解决可并堆加强版,然后除了前两个数据和 Hack 的最后一个全 MLE:
CPP
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC optimize(d)
#pragma GCC optimize(s)
#pragma G++ optimize(1)
#pragma G++ optimize(2)
#pragma G++ optimize(3,"Ofast","inline")
#pragma G++ optimize(d)
#pragma G++ optimize(s)
using namespace std;
int cnt,root[1000005];
struct Node
{
	int ls,rs,key,pri,sz;
}t[1000005];
int build(int x)
{
	t[++cnt].sz=1;
	t[cnt].ls=t[cnt].rs=0;
	t[cnt].key=x;
	t[cnt].pri=rand()*rand();
	return cnt;
}
void update(int u)
{
	t[u].sz=t[t[u].ls].sz+t[t[u].rs].sz+1;
}
void split(int u,int x,int& L,int& R)
{
	if(!u)
	{
		L=R=0;
		return ;
	}
	if(t[u].key<=x)
	{
		L=u;
		split(t[u].rs,x,t[u].rs,R);
	}
	else
	{
		R=u;
		split(t[u].ls,x,L,t[u].ls);
	}
	update(u);
}
void Split(int u,int x,int& L,int& R)
{
	if(!u)
	{
		L=R=0;
		return ;
	}
	if(t[t[u].ls].sz+1<=x)
	{
		L=u;
		Split(t[u].rs,x-t[t[u].ls].sz-1,t[u].rs,R);
	}
	else
	{
		R=u;
		Split(t[u].ls,x,L,t[u].ls);
	}
	update(u);
}
int merge(int L,int R)
{
	if(L==0||R==0)return L+R;
	int l,r;
	if(t[L].pri>t[R].pri)
	{
		split(R,t[L].key,l,r);
		t[L].ls=merge(t[L].ls,l);
		t[L].rs=merge(t[L].rs,r);
		update(L);
		return L;
	}
	split(L,t[R].key,l,r);
	t[R].ls=merge(t[R].ls,l);
	t[R].rs=merge(t[R].rs,r);
	update(R);
	return R;
}
int _kth(int u,int k)
{
	if(k==t[t[u].ls].sz+1)return u;
	if(k<=t[t[u].ls].sz)return _kth(t[u].ls,k);
	if(k>t[t[u].ls].sz)return _kth(t[u].rs,k-t[t[u].ls].sz-1);
}
int kth(int u,int k){return t[_kth(u,k)].key;}
int find(int x)
{
	if(root[x]==x)return root[x];
	return root[x]=find(root[x]);
}
int Merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		if(t[x].pri>t[y].pri)
		{
			root[y]=x;
			merge(x,y);
			return x;
		}
		else
		{
			root[x]=y;
			merge(x,y);
			return y;
		}
	}
}
int n,i,m,op,x,y,z,a[1000005];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	srand(time(NULL));
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
		root[i]=build(a[i]);
	}
	while(m--)
	{
		cin>>op>>x;
		if(op==0)
		{
			cin>>y;
			int heap=find(x),L,R,p;
			split(heap,a[y],L,R);
			split(L,a[y]-1,L,p);
			int minn;
			Split(p,1,minn,p);
			//cout<<":"<<L<<":"<<R<<":"<<p<<":"<<minn<<endl;
			root[find(x)]=merge(merge(L,p),R);
		}
		else if(op==1)
		{
			int heap=find(x),minn=_kth(heap,1);
			cout<<t[minn].key<<endl;
			//Merge(minn,heap); 
		}
		else if(op==2)
		{
			cin>>y;
			Merge(x,y);
		}
		else
		{
			cin>>y>>z;
			int heap=find(x),L,R,p;
			split(heap,a[y],L,R);
			split(L,a[y]-1,L,p);
			int minn;
			Split(p,1,minn,p);
			t[minn].key=z;
			root[find(x)]=merge(merge(L,minn),merge(p,R));
			a[y]=z;
		}
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...