题意:给一个数组,然后问你在区间(L,R)里相同数字出现的最多次数。。
分析:因为是非降序的,所有相同的元素会聚集到一起。这个就可以把整个数组进行编码,变成出现次数为数组的值的数组,然后求区间的最大值即可。
比如-1,1,1,2,2,2,4就可以编码成(-1,1)(1,2)(2,4)(4,1),其中(a,b)表示有b个连续的a
G[i]为第i段的值,cnt[i]为第i段的个数,F[i]为第i段的左端点位置,R[i]为第i段右端点的位置,pos[i]为第i个数所在的段
// File Name: 11235.cpp // Author: zlbing // Created Time: 2013/3/9 21:32:31 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,n) for(int i=0;i<n;i++) #define REP1(i,n) for(int i=1;i<n+1;i++) #define MAXN 100050 int d[MAXN][20]; int G[MAXN]; int cnt[MAXN]; int F[MAXN],R[MAXN]; int pos[MAXN*2]; int len; void init_RMQ(int n) { for(int i=1;i<=n;i++)d[i][0]=cnt[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) d[i][j]=max(d[i][j-1],d[i+(1<<j-1)][j-1]); } int max_RMQ(int a,int b){ int k=0; while((1<<k)<=b-a+1)k++; return max(d[a][k-1],d[b-(1<<(k-1))+1][k-1]); } int main(){ int n,q; while(~scanf("%d",&n)){ if(!n)break; scanf("%d",&q); CL(cnt,0); len=0; int a,b; REP1(i,n){ scanf("%d",&a); if(len==0){ G[++len]=a; cnt[len]++; F[len]=1; pos[i]=len; }else{ if(a==G[len]){ cnt[len]++; pos[i]=len; } else { R[len]=i-1; G[++len]=a; cnt[len]++; F[len]=i; pos[i]=len; } } } R[len]=n; init_RMQ(len); REP(i,q){ scanf("%d%d",&a,&b); int aa=pos[a]; int bb=pos[b]; if(aa==bb)printf("%d\n",b-a+1); else{ int ans=R[aa]-a+1; ans=max(b-F[bb]+1,ans); ans=max(ans,max_RMQ(aa+1,bb-1)); printf("%d\n",ans); } } } return 0; }