描述:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 17576 | Accepted: 6344 |
Description
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.
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
Source
题意:
给出n个数和Q个询问(l,r),对于每个询问求出(l,r)之间连续出现次数最多的次数。
思路:
将原序列转换一下:
if(a[i]==a[i-1])num[i]=num[i-1]+1;
else num[i]=1;
对于每个询问(l,r),分为两个部分,前半部分求与l之前相同的数的个数直到t,后半部分从t开始直接用RMQ求解最大值就行了,当然也可以线段树去做。
最后结果为max(前半部分,后半部分)。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
using namespace std;
#define mst(ss,b) memset(ss,b,sizeof(ss));
#define For(i,j,n) for(int i=j;i<=n;i++)
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
const int N=1e5+10;
int n,q;
int a[N],num[N];
int dp[N][20];
int rmq_init(){
for(int i=1; i<=n; i++)dp[i][0]=num[i];
for(int j=1; (1<<j)<=n; j++)
for(int i=1; i+(1<<j)-1<=n; i++)
dp[i][j]=max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
}
int rmq(int l,int r){
if(l>r)return 0;//这个必加
int k=(int)(log(r-l+1.0)/log(2.0));
return max(dp[l][k], dp[r-(1<<k)+1][k]);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while(~scanf("%d",&n)&&n){
read(q);
mst(num, 0);
mst(dp, 0);
for(int i=1; i<=n; i++)read(a[i]);
for(int i=1; i<=n; i++){
if(i==1){ num[i]=1; continue;}
if(a[i]==a[i-1])num[i]=num[i-1]+1;
else num[i]=1;
}
rmq_init();
int l,r;
while(q--){
read(l);read(r);
int t=l;
while(t<=r && a[t]==a[t-1])t++;
int ans=rmq(t, r);
ans=max(ans, t-l);
printf("%d\n", ans);
}
}
return 0;
}