http://poj.org/problem?id=3368
追完韩剧 想起这题来了 想用线段树搞定来着 结果没想出来。。然后想RMQ 想出来了
算是离散吧 把每个数出现的次数以及开始的位置及结束的位置记录下来 以次数进行RMQ 再特殊处理下区间端点就OK 了
WA一次 盯了半小时 原来少了个=号 好吧好吧。。

1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<cmath> 7 using namespace std; 8 #define N 200005 9 struct node 10 { 11 int s,e,a; 12 }p[N]; 13 int b[N],f[N],fm[N][40]; 14 void init(int n) 15 { 16 int i,j,o = floor(log10(double(n))/log10(double(2))); 17 for(j = 1; j <= o ; j++) 18 for(i = 1; i <= n+1-(1<<j) ; i++) 19 { 20 fm[i][j] = max(fm[i][j-1],fm[i+(1<<(j-1))][j-1]); 21 } 22 } 23 int main() 24 { 25 int i,n,q; 26 while(scanf("%d",&n)&&n) 27 { 28 scanf("%d",&q); 29 for(i = 1; i <= n ;i++) 30 { 31 scanf("%d",&b[i]); 32 } 33 int g = 0; 34 p[++g].a = b[1]; 35 p[g].s = 1;f[1] = 1; 36 int pre = b[1]; 37 for(i = 2; i <= n ; i++) 38 { 39 if(b[i]!=pre) 40 { 41 p[g].e = i-1; 42 p[++g].a = b[i]; 43 p[g].s = i; 44 pre = b[i]; 45 } 46 f[i] = g; 47 } 48 p[g].e = n; 49 for(i = 1; i <= g ; i++) 50 fm[i][0] = p[i].e-p[i].s+1; 51 init(g); 52 while(q--) 53 { 54 int a,b,t; 55 scanf("%d%d",&a,&b); 56 if(a>b) 57 { 58 t = a;a=b;b=t; 59 } 60 int x = f[a],y = f[b]; 61 if(x==y) 62 printf("%d ",b-a+1); 63 else if(y-x==1) 64 { 65 int maxz = max(b-p[y].s+1,p[x].e-a+1); 66 printf("%d ",maxz); 67 } 68 else 69 { 70 int maxz = max(b-p[y].s+1,p[x].e-a+1); 71 x++;y--; 72 int o = floor(log10(double(y-x+1))/log10(double(2))); 73 int mm = max(fm[x][o],fm[y-(1<<o)+1][o]); 74 printf("%d ",max(mm,maxz)); 75 } 76 } 77 } 78 return 0; 79 }