Frequent values
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 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次询问,求出区间[ i , j ]出现次数最多的数的个数。
思路:
ST在线算法,只是对于有些区间把出现次数比较多的那一段给切了一部分,对于那部分特判一下就好。
借鉴了下别人的博客。
示例程序
Source Code
Problem: 3368 Code Length: 1567B
Memory: 8628K Time: 1500MS
Language: GCC Result: Accepted
#include <stdio.h>
#include <math.h>
int a[100000],f[100000][20];
int max(int x,int y)
{
if(x>y)
{
return x;
}
else
{
return y;
}
}
void bulid(int n)
{
int i,i1,logn,start,end,temp,r;
for(i=0;n>i;i++)
{
f[i][0]=1;
}
for(i=1;n>=(1<<i);i++)
{
for(i1=0;n>i1+(1<<i)-1;i1++)
{
f[i1][i]=max(f[i1][i-1],f[i1+(1<<i-1)][i-1]);
temp=a[i1+(1<<i-1)-1]; //特判一下边界
start=i1+(1<<i-1)-1;
end=start;
r=i1+(1<<i)-1;
while(start>=i1&&a[start]==temp)
{
start--;
}
while(end<=r&&a[end]==temp)
{
end++;
}
f[i1][i]=max(f[i1][i],end-start-1);
}
}
}
int rmq(int x,int y)
{
int logn,num,start,end,temp;
logn=(int)(log((double)(y-x+1))/log(2.0));
num=max(f[x][logn],f[y-(1<<logn)+1][logn]);
temp=a[x+(1<<logn)-1]; //这也一样
start=x+(1<<logn)-1;
end=start;
while(start>=x&&a[start]==temp)
{
start--;
}
while(end<=y&&a[end]==temp)
{
end++;
}
num=max(num,end-start-1);
return num;
}
int main()
{
int n,q,i,x,y;
scanf("%d",&n);
while(n!=0)
{
scanf("%d",&q);
for(i=0;n>i;i++)
{
scanf("%d",&a[i]);
}
bulid(n);
for(i=1;q>=i;i++)
{
scanf("%d %d",&x,&y);
x--;
y--;
printf("%d\n",rmq(x,y));
}
scanf("%d",&n);
}
return 0;
}