题目给出了一个非下降序列,求给定的一个区间内重复个数最多是多少。
这题可以用RMQ来做,比较区间两端的个数和不同于最大重复个数(RMQ)。
View Code
1 /* 2 Author:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <iostream> 8 #include <cmath> 9 #include <cstring> 10 #include <algorithm> 11 #include <string> 12 #include <vector> 13 #include <queue> 14 #include <stack> 15 #include <map> 16 #include <set> 17 using namespace std; 18 19 20 const int maxn=100000+10; 21 int value[maxn],value_pos[maxn<<1],coun[maxn],sta[maxn<<1],end[maxn<<1]; 22 int sign[maxn<<1],pos[maxn<<1]; 23 int n,num; 24 int Max[maxn][20]; 25 int maxx(int a,int b) 26 { 27 return a>b?a:b; 28 } 29 void init_rmp() 30 { 31 for(int i=1;i<=num;i++) 32 { 33 Max[i][0]=coun[i]; 34 } 35 for(int i=1;(1<<i)<=num;i++) 36 { 37 for(int j=1;j+(1<<(i-1))<=num;j++) 38 { 39 Max[j][i]=maxx(Max[j][i-1],Max[j + (1 << (i-1))][i-1]); 40 } 41 } 42 } 43 int max_rmp(int l,int r) 44 { 45 int k=log(r-l+1.0)/log(2.0); 46 return maxx(Max[l][k],Max[r-(1<<k)+1][k]); 47 } 48 int main() 49 { 50 int q; 51 while(~scanf("%d",&n),n) 52 { 53 scanf("%d",&q); 54 memset(coun,0,sizeof(coun)); 55 memset(sign,0,sizeof(sign)); 56 num=1; 57 scanf("%d",&value[1]); 58 coun[num]++; 59 sta[maxn+value[1]]=1; 60 sign[maxn+value[1]]=1; 61 pos[1]=num; 62 value_pos[maxn+value[1]]=num; 63 for(int i=2;i<=n;i++) 64 { 65 scanf("%d",&value[i]); 66 if(!sign[maxn+value[i]]) 67 { 68 sign[maxn+value[i]]=1; 69 num++; 70 coun[num]++; 71 end[maxn+value[i-1]]=i-1; 72 pos[i]=num; 73 sta[maxn+value[i]]=i; 74 value_pos[maxn+value[i]]=num; 75 } 76 else coun[num]++,pos[i]=num;; 77 } 78 end[maxn+value[n]]=n; 79 80 init_rmp(); 81 82 while(q--) 83 { 84 int x,y; 85 int ans=-1; 86 scanf("%d%d",&x,&y); 87 if(value[x] == value[y])ans=y-x+1; 88 else 89 { 90 int xx=pos[end[maxn+value[x]]]+1; 91 int yy=pos[sta[maxn+value[y]]]-1; 92 if(yy >= xx) 93 { 94 ans=max_rmp(xx,yy); 95 } 96 int tmpx=end[maxn+value[x]] - x + 1; 97 int tmpy=y -sta[maxn+value[y]] + 1; 98 if(tmpx>ans)ans=tmpx; 99 if(tmpy>ans)ans=tmpy; 100 } 101 printf("%d\n",ans); 102 } 103 } 104 return 0; 105 }