感觉不太好做吧,算法训练指南P198 UVA11235和这道题的解释一样。大家可以参考一下。
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 12436 | Accepted: 4554 |
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
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 10001000
#define LL __int64
//#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
const int maxn = 101000;
using namespace std;
int sum[maxn];
int f[maxn];
int l[maxn];
int r[maxn];
int dp[maxn][20];
int main()
{
int n, m;
while(~scanf("%d",&n))
{
if(!n)
break;
scanf("%d",&m);
int t = 1;
int L = 1, R = 1;
for(int i = 1; i <= n; i++)
{
scanf("%d",&f[i]);
if(f[i] == f[i-1] && i != 1)
{
R++;
t++;
}
if((f[i] != f[i-1] && i != 1) || i == n)
{
for(int j = L; j <= R; j++)
{
sum[j] = t;
l[j] = L;
r[j] = R;
}
t = 1;
L = R = i;
}
}
for(int j = L; j <= n; j++)
{
sum[j] = t;
l[j] = L;
r[j] = n;
}
memset(dp, 0 , sizeof(dp));
for(int i = 1; i <= n; i++)
dp[i][0] = sum[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 x, y;
while(m--)
{
scanf("%d %d",&x, &y);
if(x > y)
swap(x, y);
L = r[x];
R = l[y];
if(L >= y)
{
printf("%d\n",y-x+1);
continue;
}
if(R <= x)
{
printf("%d\n",y-x+1);
continue;
}
int ans = max(L-x+1, y-R+1);
if(L == R-1)
{
printf("%d\n",ans);
continue;
}
L++;
R--;
int k=(int)(log(double(R-L+1))/log((double)2));
ans = max(ans, max(dp[L][k], dp[R-(1<<k)+1][k]));
printf("%d\n",ans);
}
}
return 0;
}