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
题意
多组数据,每组数据第一行两个数字n,q,表示n个整数和q次询问,然后给n个数字,每次询问两个数字i,j,表示区间【i,j】中出现次数最多的值所出现的次数。
解题思路
离散化+维护区间最大值。
1.ai的范围在-100000~100000之间,其实本题直接加上100000可是可行的,担有些题目数据远远超过100000,所以还是用离散化好点。
2.肯定要记录每个点出现的左端点和右端点。
第二行是原数组,第三行是离散化后数组,第四行是左端点数组,第五行是右端点数组。
3.两个端点值可能只取了部分,即可能有些端点值在区间外,所以两个端点需要特判一下,假设区间为【q,w】,左端点的相同数字出现次数就是w-l[temp[w]]+1,右端点就是r[temp[q]]-q+1,代码如下
int ans=max(w-l[temp[w]]+1,r[temp[q]]-q+1);
因为我们已经将ai离散化处理过了,所以只需要求一下for (int i=q+1;i<=w-1;i++)
数字i出现的最大值就好了,线段树查询操作logn,完毕。
4.多组输入,一定要memset,血的教训。
AC代码
#include <iostream>
#include <cstring>
#define ll long long
#define lson left,mid,k<<1
#define rson mid+1,right,k<<1|1
#define imid int mid=(left+right)>>1
using namespace std;
int a[100005],temp[100005],l[100005],r[100005];
int ql,qr;
struct node
{
int l;
int r;
int maxn;
}que[200005*4];
void push_up(int k)
{
que[k].maxn=max(que[k<<1].maxn,que[k<<1|1].maxn);
}
void build(int left,int right,int k)
{
que[k].l=left;
que[k].r=right;
if (left==right)
{
que[k].maxn=a[left];
return;
}
imid;
build(lson);
build(rson);
push_up(k);
}
int query(int left,int right,int k)
{
if (qr<left||ql>right)
return 0;
if (ql<=left&&right<=qr)
return que[k].maxn;
imid;
return max(query(lson),query(rson));
}
int main()
{
//freopen("123.txt","w+",stdout);
int n,m,q,w;
while (true)
{
memset(a,0,sizeof(a));
scanf("%d",&n);
if (n==0)
return 0;
scanf("%d",&m);
int x=1,pre,t;
scanf("%d",&pre);
temp[1]=x;
a[x]++;
l[1]=1;
for (int i=2;i<=n;i++)
{
scanf("%d",&t);
if (t!=pre)
{
r[x]=i-1;
x++;
l[x]=i;
}
a[x]++;
pre=t;
temp[i]=x;
}
r[x]=n;
/* for (int i=1;i<=n;i++) printf("%d%c",temp[i],i!=n?' ':'\n'); for (int i=1;i<=n;i++) printf("%d%c",l[i],i!=n?' ':'\n'); for (int i=1;i<=n;i++) printf("%d%c",r[i],i!=n?' ':'\n'); return 0; */
build(1,x,1);
while (m--)
{
scanf("%d%d",&q,&w);
//printf("%d %d\n\n",temp[q-1],temp[w-1]);
if (temp[q]==temp[w])
printf("%d\n",w-q+1);
else
{
ql=temp[q]+1;
qr=temp[w]-1;
int ans=max(w-l[temp[w]]+1,r[temp[q]]-q+1);
if (ql<=qr)
ans=max(ans,query(1,x,1));
printf("%d\n",ans);
}
}
}
}