【待完善】UVA-11235:Frequent values

Frequent values

来源:UVA

标签:数据结构,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 .

输入

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’.

输出

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!

输入样例

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

输出样例

1
4
3

参考代码

#include
#include
#include
#include
#define INF 0x3f3f3f3f
#define MAXN 100005
using namespace std;

int value[MAXN];//value[i]:第i段的值
int cnt[MAXN];//num[i]:第i段的值的个数 
int num[MAXN];//num[i]:原序列位置i在哪一段中 
int left[MAXN];//left[i]:第i段左端点的位置 
int right[MAXN];//right:第i段右端点的位置 
int no;//段的编号 

int d[MAXN][18];
void RMQ_init(){
	for(int i=1; i<=no; i++){
		d[i][0]=cnt[i];
	}
	for(int j=1; (1<<j)<=no; j++){
		for(int i=1; i+(1<<j)-1<=no; i++){
			d[i][j]=max(d[i][j-1], d[i+(1<<(j-1))][j-1]);
		}
	}
}

int RMQ(int L,int R){
	if(R<L)return 0;
	int k=0;
	while((1<<(k+1)) <= R-L+1){
		k++;
	}
	return max(d[L][k], d[R-(1<<k)+1][k]);
}

int main(){
	int n,q;
	while(scanf("%d%d",&n,&q)==2 && n){
		memset(value,INF,sizeof(value));
		memset(cnt,0,sizeof(cnt));
		no=0;
		
		int v;
		for(int i=1;i<=n;i++){
			scanf("%d",&v);
			if(v==value[no]){
				right[no]++;
			}else{
				no++;
				value[no]=v;
				left[no]=right[no]=i;
			}
			num[i]=no;
			cnt[no]++;
		}
		
		RMQ_init();
		
		int l,r; 
		while(q--){
			scanf("%d%d",&l,&r);
			if(num[l]==num[r]){
				printf("%d\n",r-l+1);
				continue;
			}
			int c1=right[num[l]]-l+1;
			int c2=r-left[num[r]]+1;
			int c3=RMQ(num[l]+1,num[r]-1);
			printf("%d\n",max(c1,max(c2,c3)));
		}
	}
	return 0;
}

你可能感兴趣的:(【记录】算法题解)