频繁出现的数值 uva11235 【rmq】

You are given a sequence of n integers a1, a2, . . . , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , . . . , aj . Input The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1, . . . , an (−100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, . . . , n − 1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the query. The last test case is followed by a line containing a single ‘0’. Output For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range. Note: A naive algorithm may not run in time!

Sample Input

10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0

Sample Output

1 4 3

以相同的数值作为一个块

sum的空间大小是cnt  其他的空间大小都是n  

num[i] 意思是a[i]这个数是属于第几个块

lef是a[i]的左边界 rig同理

dp里面存每个块的最大长度

注意边界处理 》》查询l r时 a[l] a[r]的数不要查 查lr范围内的 也就是开区间的内容

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define maxn 100500
#define inf 0x3f3f3f3f
#define clr(a,b) memset(a,b,sizeof(a));
using namespace std;
int lef[maxn],rig[maxn],a[maxn],num[maxn],dp[maxn][64],sum[maxn],cnt;
//rig and lef of range are like a lenth.
void rmq_init()
{
	for(int i=1;i<=cnt;i++)
	{
		dp[i][0]=sum[i];
	}
	for(int j=1;(1<<j)<=cnt;j++)
	{
		for(int i=1;i+(1<<j)-1<=cnt;i++)
		{
			dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
		}
	}
	/*for(int i=1;i<=cnt;i++)
	{
		for(int j=1;j<=cnt;j++)
		cout<<dp[i][j]<<'\t';
	cout<<endl;
	}*/
} 

int rmqq(int l,int r)
{
	int k=0;
	while(1<<k <=r-l+1) k++;
	k--;
	int ans=0;
	ans=max(dp[l][k],dp[r-(1<<k)+1][k]);//区间可能有重合 保证了结果的正确性 
	return ans;
}

int main()
{
	int n,q;
	while(cin>>n&&n)
	{
		clr(sum,0)
		cnt=0;
		cin>>q;
		a[0]=inf;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			num[i]=(a[i]==a[i-1])?cnt:++cnt;
			sum[cnt]++;
			if(a[i]==a[i-1]) lef[i]=lef[i-1];
			else lef[i]=i;			
		}
		rig[n]=n;
		for(int i=n-1;i>=1;i--)
		{
			if(a[i]==a[i+1]) rig[i]=rig[i+1];
			else rig[i]=i;
		}
		rmq_init();
		while(q--)
		{
			int l,r;
			cin>>l>>r;
			
			if(num[l]==num[r])
			{
				cout<<r-l+1<<endl;
				continue;
			}			
			int inx=num[l]+1;			
			int iny=num[r]-1;
			int in=rmqq(inx,iny);			
			int ans=max(max((rig[l]-l+1),(r-lef[r]+1)),in);
			cout<<ans<<endl;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41544329/article/details/82833785
RMQ