POJ 3368 Frequent values
洛谷 UVA11235
https://www.luogu.org/problemnew/show/UVA11235
洛谷 SP1684
https://www.luogu.org/problemnew/show/SP1684
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
真的是好奇怪鸭!一模一样的题,竟然一道是蓝题一道是紫题。。。不过我就不要脸..咳咳,不客气地全切了。
一开始只能想到暴力,但是TLE没跑了,所以就开始开发更优地解法,看过洛谷的题解后想到了RMQ的一种变形。
是的,一开始我的思路也被限制住了,RMQ不是区间求最值么?什么时候可以求元素出现次数了?
这么想的我说明自己还是个弱鸡。
这道题的RMQ比较难想,这里的f数组表示的是从i开始的2^j个元素中重复最多的次数,注意是次数。
这里我们还需要注意处理一下左右端点,因为可能会出现答案存在的区间横跨中间点的情况出现,所以要在询问出解的时候特殊判定一下。
不多说了,我觉得这道题够一道紫题,毕竟这真的是我自己A的第一道紫题哈哈哈哈
AC c o d e:
#include<cstdio> #include<cmath> #include<iostream> #define N 100001 using namespace std; int n,q,a[N],dp[N],f[N][17],lg[N]; int ask(int l,int r) { if(l>r) return 0; int k=lg[r-l+1]; return max(f[l][k],f[r-(1<<k)+1][k]); } int main() { while(~scanf("%d%d",&n,&q)&&n) { dp[1]=1; for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(i>1) { if(a[i]==a[i-1]) dp[i]=dp[i-1]+1; else dp[i]=1; } } for(int i=1;i<=n;i++) f[i][0]=dp[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); while(q--) { int l,r; scanf("%d%d",&l,&r); int now=l; while(now<=r && a[now]==a[now-1]) now++; printf("%d\n",max(now-l,ask(now,r))); } } }