[POI2014] KUR-Couriers

  • 可持久化线段树
  • 维护由任意一段区间得到的权值线段树
  • 线段树的深度:\(ceil(log_{2}(n))+1\)
  • 由于询问的特殊性,我们可以直接在线段树上二分,而不需要另写查询函数,从而节省掉1个log的复杂度
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int tot,root[500005];
int read1()
{
	char cc=getchar();
	while(!(cc>=48&&cc<=57))
	{
		if(cc=='-')
		{
			break;
		}
		cc=getchar();
	}
	bool f=false;
	int s=0;
	if(cc=='-')
	{
		f=true;
	}
	else
	{
		s=cc-48;
	}
	while(1)
	{
		cc=getchar();
		if(cc>=48&&cc<=57)
		{
			s=s*10+cc-48;
		}
		else
		{
			break;
		}
	}
	if(f==true)
	{
		s=-s;
	}
	return s;
}
struct t1
{
	int l,r,cnt;
}t[11000005];
int build(int l,int r)
{
	if(l==r)
	{
		tot++;
		t[tot].cnt=0;
		return tot;
	}
	int mid=(l+r)>>1;
	tot++;
	int p=tot;
	t[p].l=build(l,mid);
	t[p].r=build(mid+1,r);
	t[p].cnt=0;
	return tot;
}
int insert(int c,int q,int l,int r)
{
	tot++;
	int p=tot;
	if(c==l&&l==r)
	{
		t[p].cnt=t[q].cnt+1;
		return p;
	}
	int mid=(l+r)>>1;
	if(c<=mid)
	{
		t[p].l=insert(c,t[q].l,l,mid);
		t[p].r=t[q].r;
	}
	else
	{
		t[p].r=insert(c,t[q].r,mid+1,r);
		t[p].l=t[q].l;
	}
	t[p].cnt=t[t[p].l].cnt+t[t[p].r].cnt;
	return p;
}
/*
int ask(int l,int r,int p,int u,int v)
{
	if(l<=u&&v<=r)
	{
		return t[p].cnt;
	}
	int mid=(u+v)>>1;
	int ans=0;
	if(l<=mid)
	{
		ans=ans+ask(l,r,t[p].l,u,mid);
	}
	if(r>mid)
	{
		ans=ans+ask(l,r,t[p].r,mid+1,v);
	}
	return ans;
}
*/
int main()
{
//	freopen("P3567_53.in","r",stdin);
//	cout<<500000*20*4*3/1024/1024<<endl;
	int n,m;
	cin>>n>>m;
	root[0]=build(1,n);
	for(int i=1;i<=n;i++)
	{
		int a=read1();
		root[i]=insert(a,root[i-1],1,n);
	}
	for(int i=1;i<=m;i++)
	{
		int u,v,len;
		u=read1();
		v=read1();
		len=v-u+1;
		int l=1,r=n,sum=len;
		u=root[u-1];v=root[v];
		bool f=true;
		while(l<r)
		{
			int mid=(l+r)>>1;
			//int cnt=ask(l,mid,root[v],1,n)-ask(l,mid,root[u-1],1,n);
			int cnt=t[t[v].l].cnt-t[t[u].l].cnt;
			if(2*cnt>len)
			{
				r=mid;
				sum=cnt;
				u=t[u].l;
				v=t[v].l;
			}
			else if(2*(sum-cnt)>len)
			{
				l=mid+1;
				sum=sum-cnt;
				u=t[u].r;
				v=t[v].r;
			}
			else
			{
				f=false;
				break;
			}
		}
		if(f==true)
		{
			printf("%d\n",l);
		}
		else
		{
			printf("0\n");
		}
	}
	return 0;
}
posted @ 2024-01-23 17:05  D06  阅读(2)  评论(0编辑  收藏  举报