poj-3368 Frequent values 线段树

题目链接


#include "stdio.h"
#include "math.h"
#include "string.h"
#include "algorithm"
using namespace std;
const int maxn = 100005;
int n,m,x,y,ans;
int num[maxn];
struct node
{
	int mmax,lmax,rmax;
	int ln,rn;
}tree[maxn<<2];
void PushUp( int rt )
{
	tree[rt].ln = tree[rt<<1].ln;
	tree[rt].rn = tree[rt<<1|1].rn;
	tree[rt].mmax = max( tree[rt<<1].mmax,tree[rt<<1|1].mmax );
	tree[rt].lmax = tree[rt<<1].lmax;
	tree[rt].rmax = tree[rt<<1|1].rmax;
	if( tree[rt<<1].rn == tree[rt<<1|1].ln )
	{
		tree[rt].mmax = max( tree[rt].mmax,tree[rt<<1].rmax + tree[rt<<1|1].lmax );
		if( tree[rt<<1].ln == tree[rt<<1|1].ln )
			tree[rt].lmax = tree[rt<<1].lmax + tree[rt<<1|1].lmax;
		if( tree[rt<<1].rn == tree[rt<<1|1].rn )
			tree[rt].rmax = tree[rt<<1].rmax + tree[rt<<1|1].rmax;
	}
}
void BuildTree( int rt,int ld,int rd )
{
	if( ld == rd )
	{
		tree[rt].mmax = tree[rt].lmax = tree[rt].rmax = 1;
		tree[rt].ln = tree[rt].rn =	num[ld];
		return;
	}
	int mid = (ld+rd)>>1;
	BuildTree( rt<<1,ld,mid );
	BuildTree( rt<<1|1,mid+1,rd );
	PushUp( rt );
}
int query( int rt,int ld,int rd )
{
	if( x <= ld && rd <= y )
	{
		return tree[rt].mmax;
	}
	if( x > rd || y < ld )	return 0;
	int mid = ( ld+rd )>>1;
	int Max = max( query( rt<<1,ld,mid ),query( rt<<1|1,mid+1,rd ));
	if( tree[rt<<1].rn == tree[rt<<1|1].ln && x <= mid && y > mid )
	{
		Max = max( Max,min( tree[rt<<1].rmax,mid-x+1 ) + min( tree[rt<<1|1].lmax,y-mid) );
	}
	return Max;
}
int main()
{
	//freopen("data.txt","r",stdin);
	while( scanf("%d",&n) != EOF,n )
	{
		scanf("%d",&m);
		for( int i = 1; i <= n; i ++ )
		{
			scanf("%d",&num[i]);
		}
		BuildTree( 1,1,n );
		for( int i = 1; i <= m; i ++ )
		{
			scanf("%d%d",&x,&y);
			ans = 0;
			printf("%d\n",query( 1,1,n ));
		}
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值