題意:給你一串數列,而後給你一個起終位置對,問你這個段序列裏出現最多的出現了幾回。ios
思路:一段序列裏,無非就是三種狀況,1,一組相同的數,2兩組相同,3,3組或者更多組數,這樣咱們隊每一組數的開頭結束位置記錄一下,而後對每次詢問判斷一下幾組數,分別討論,多組的就分爲第一組,最後一組,中間多組,中間直接rmq就能夠了。ide
代碼:oop
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <stdlib.h> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #define loop(s,i,n) for(i = s;i < n;i++) 10 #define cl(a,b) memset(a,b,sizeof(a)) 11 int num[100005],b[100005],rt[100005],lt[100005],a[100005],maxd[100005][17]; 12 using namespace std; 13 void init(int n) 14 { 15 int i,j; 16 for(i = 1;i <= n;i++) 17 maxd[i][0] = a[i]; 18 19 for(j = 1;(1<<j) <= n;j++) 20 { 21 for(i = 1;i+(1<<j)-1<=n;i++) 22 { 23 maxd[i][j] = max(maxd[i][j-1],maxd[i+(1<<(j-1))][j-1]); 24 } 25 } 26 } 27 int maxrmq(int l,int r) 28 { 29 int k = 0; 30 while(1<<(k+1) <= r-l+1)k++; 31 return max(maxd[l][k],maxd[r-(1<<k)+1][k]); 32 33 } 34 int main() 35 { 36 int n,q; 37 38 while(scanf("%d",&n)&&n) 39 { 40 int i,j; 41 scanf("%d",&q); 42 loop(1,i,n+1) 43 { 44 scanf("%d",&b[i]); 45 } 46 int cnt,leap; 47 cnt = 1; 48 leap = b[1]; 49 for(i = 0;i <= n;i++) 50 a[i] = num[i] = 0; 51 lt[1] = 1; 52 for(i = 1;i <= n;i++) 53 { 54 if(leap != b[i]) 55 rt[cnt] = i-1,cnt++,lt[cnt] = i,leap = b[i]; 56 num[i] = cnt; 57 a[cnt]++; 58 } 59 rt[cnt] = n; 60 init(cnt); 61 62 while(q--) 63 { 64 int l,r,a,b,c; 65 scanf("%d %d",&l,&r); 66 if(num[l] == num[r]) 67 b = r-l+1; 68 else if(num[r]-num[l] > 1) 69 { 70 a = rt[num[l]]-l+1; 71 b = r-lt[num[r]]+1; 72 c = maxrmq(num[l]+1,num[r]-1); 73 b = max(a,b); 74 b = max(b,c); 75 } 76 else 77 { 78 a = rt[num[l]]-l+1; 79 b = r-lt[num[r]]+1; 80 b = max(a,b); 81 } 82 83 printf("%d\n",b); 84 } 85 } 86 return 0; 87 }