给你一个由n个数字组成的非降序序列(这是重要条件)。
有m次询问,每次询问区间【L,R】之间出现最多的数字出现的次数。
该题只涉及查询不涉及修改选用RMQ中的ST算法
我们用数组counts,按顺序统计一个数字连续·出现的次数,这个数子保存在value中(本题其实不需要保存,如果询问是哪个数则需要)
然后用一个结构统计一个下标所在的区间的左右范围,以及当前下标的数字在counts中属于哪个位置。
然后对counts进行RMQ初始化,查询区间最大值,
对于l,r的询问
我们ans=max(从l到l所在段的结束处元素数量,从r到r开始出的元素数量,位于l和r之间的最大值(rmq查询));
注意l和r位于一个区间的情况,已经找l,r中间的区间的时候,可能会出现最后L>R的情况。
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 11241 | Accepted: 4110 |
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<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int p,l,r;
}data[100100];
int p;
int value[100100];
int counts[100100];
int dp[100050][60];
int n,m;
void init()
{
for(int i=1;i<=p;i++)
dp[i][0]=counts[i];
int k=floor(log((double)(n+1))/log(2.0));
int m;
for(int j=1;j<=k;j++)
for(int i=1;i+(1<<j)-1<=p;i++)
{
m=i+(1<<(j-1));
dp[i][j]=max(dp[i][j-1],dp[m][j-1]);
}
}
int rmq(int i,int j)
{
int m=floor((log((double)(j-i+1))/log(2.0)));
int x=max(dp[i][m],dp[j-(1<<m)+1][m]);
return x;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
int l=0,r=0,v=0,tmp;
p=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&tmp);
if(tmp!=v && l!=0)
{
counts[p]=r-l+1;
value[p]=v;
for(int j=l;j<=r;j++)
data[j].l=l,data[j].r=r,data[j].p=p;
p++;
r++;
l=r;
v=tmp;
}
else
r++;
if(l==0)
{
l=1;
v=tmp;
}
}
counts[p]=r-l+1;
value[p]=v;
for(int j=l;j<=r;j++)
data[j].l=l,data[j].r=r,data[j].p=p;
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&l,&r);
int L,R;
if(data[l].p==data[r].p)
printf("%d\n",r-l+1);
else
{
L=data[l].p+1;
R=data[r].p-1;
int ans=data[l].r-l+1;
ans=max(ans,r-data[r].l+1);
if(L<=R)ans=max(ans,rmq(L,R));
printf("%d\n",ans);
}
}
}
return 0;
}