给定一个数组,其中的元素满足非递减顺序。任意给定一个区间[i,j],求其中某个元素重复出现的最大次数。
题目描述
输入
多组数据输入。每组数据的第一行包含两个整数n和q(1<=n,q<=100000),下一行包含n个整数a1,...,an(-100000<=ai<=100000,i∈{1,...,n}),用空格分隔,数列是升序的(ai<=ai+1)。接下来的q行,每行包含两个整数i和j(1<=i<=j<=n),表示给定区间[i,j]。
输入结束于0(自成一行)。
输出
对输入的q个区间,每个区间输出一个整数表示该区间内重复最多的元素出现的次数,用换行分隔。
样例输入
10 3
-1 -1 1 1 1 1 3 10 10 10
2 3
1 10
5 10
0
样例输出
1
4
3
【分析】直接区间RMQ,需要注意的是更新和查找时判一下两区间交点处的情况。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 2e5+50; const int mod = 1e9+7; const double pi= acos(-1.0); typedef pair<ll,int>pii; int mx[N][18]; int mm[N],n,q; int l[N],r[N],a[N]; void init() { for(int j=1; j<=mm[n]; ++j) { for(int i=1; i+(1<<j)-1<=n; ++i) { int mid=i+(1<<(j-1)); int ll=max(i,l[a[mid]]); int rr=min(i+(1<<j)-1,r[a[mid]]); mx[i][j]=max(rr-ll+1,max(mx[i][j-1],mx[i+(1<<(j-1))][j-1])); } } } int getmx(int ll,int rr) { int k = mm[rr-ll+1]; int l1=max(ll,l[a[ll+(1<<k)]]); int r1=min(rr,r[a[ll+(1<<k)]]); int l2=max(ll,l[a[rr-(1<<k)+1]]); int r2=min(rr,r[a[rr-(1<<k)+1]]); int ret=1; ret=max(r1-l1+1,r2-l2+1); ret=max(ret,max(mx[ll][k],mx[rr-(1<<k)+1][k])); return ret; } int main() { mm[0]=-1; for(int i=1; i<N; ++i)mm[i]=(i&(i-1))?mm[i-1]:mm[i-1]+1; while(~scanf("%d",&n)&&n) { met(l,0); scanf("%d",&q); for(int i=1; i<=n; ++i) { scanf("%d",&a[i]); a[i]+=100000; if(!l[a[i]])l[a[i]]=i; r[a[i]]=i; mx[i][0]=1; } init(); while(q--) { int x,y; scanf("%d%d",&x,&y); printf("%d\n",getmx(x,y)); } } return 0; }