BIT&&RMQ——Poj 3368 Frequent values

###题目:

http://poj.org/problem?id=3368

###AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#define maxn 100000 + 10

using namespace std;
typedef long long LL;
LL a[maxn];
LL st[maxn],ed[maxn];
LL n;
LL N,M,K,T;
LL d[maxn][18];
void predig()
{
	  memset(d,0,sizeof(d));
    for (int i = 0; i<n; i++)
    {
        d[i][0] = st[i+1];
    }

    for (LL j = 1; (1 << j) <= n; j++)
    {
        for (LL i = 0; (i + (1 << j) - 1)<n; i++)
        {
            d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
        }
    }
}

LL rmq(LL l, LL r)
{
    LL k = 0;
    while (1 << (k + 1) <= (r - l + 1)) k++;
    return max(d[l][k], d[r - (1 << k) + 1][k]);
}

void solve()
{
	a[0] = a[1] * (-1);
	for(int i = 1; i <= n; i++)
	{
		if(a[i] == a[i-1]) st[i] = st[i-1] + 1;
		else st[i] = 1;
	}
	a[n+1] = a[n] *(-1);
  for(int i = n; i > 0; i--)
	{
		if(a[i] == a[i+1]) ed[i] = ed[i+1];
		else ed[i] = i;
	}

	predig();

  while(T--)
	{
		LL L,R;
		scanf("%lld%lld",&L,&R);
			if(ed[L] >= R)
			  printf("%lld\n",R - L + 1);
			else printf("%lld\n",max(ed[L]-L + 1,rmq(ed[L],R-1)));
	}

}

int main()
{
		while(cin>>n&&n)
		{
			scanf("%lld",&T);
			for(int i = 1; i <= n; i++)
		   scanf ("%lld",&a[i]);
			 solve();
		}
		return 0;
}

###题解:

1.正序扫描:st[maxn]标记各自出现次数:-1 (1)-1(2) 1(1) 1(2) 1 (3)1 (4)3(1) 10(1) 10 (2)10(3)

2.倒序扫描:ed[maxn]标记各自值最后出现的位置:-1 (2)-1(2) 1(6) 1(6) 1 (6)1 (6)3(7) 10(10) 10 (10)10(10)

3.当ed[L] >= R ans = R - L + 1;
当ed[L] < R ans = max(ed[L]-L + 1,rmq(ed[L],R-1))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值