POJ 3368 Frequent values

  简单的RMQ  约等于模板题.....第一次敲 给自己留个参考

  

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 
 7 #define Max(a,b) a > b ? a : b
 8 
 9 using namespace std;
10 
11 int Num[100010];
12 
13 int MaxNum[100010][15];
14 
15 int value[100010],Count[100010],Left[100010],Right[100010];
16 
17 int divide(int Num,int s,int e)
18 {
19     int mid = (s+e)/2;
20     if(Num == value[mid])
21         return mid;
22     else if(Num < value[mid])
23         return divide(Num,s,mid-1);
24     return divide(Num,mid+1,e);
25 }
26 
27 int RMQ(int L,int R)
28 {
29     if(L > R)
30         return -1;
31     else if(L == R)
32         return Count[L];
33     int k = 0;
34     while( (1<<(k+1)) <= R-L+1 )
35         ++k;
36     return Max(MaxNum[L][k],MaxNum[R-(1<<k)+1][k]);
37 }
38 
39 void RMQ_init(int n)
40 {
41     int i,j;
42     for(i = 1; i <= n; ++i)
43     {
44         MaxNum[i][0] = Count[i];
45     }
46 
47     for(j = 1; (1<<j) <= n; ++j)
48     {
49         for(i = 1; i + j - 1 <= n; ++i)
50         {
51             MaxNum[i][j] = Max(MaxNum[i][j-1],MaxNum[i+(1<<(j-1))][j-1]);
52         }
53     }
54 }
55 
56 int main()
57 {
58     int n,m,i,top,last,L,R;
59     while(scanf("%d",&n) && n)
60     {
61         scanf("%d",&m);
62 
63         top = 1;
64         last = -200010;
65         Left[0] = 1;
66 
67         for(i = 1; i <= n; ++i)
68         {
69             scanf("%d",&Num[i]);
70             if(Num[i] != last)
71             {
72                 last = Num[i];
73                 value[top] = Num[i];
74                 Left[top] = i;
75                 Right[top-1] = i-1;
76                 Count[top-1] = Right[top-1] - Left[top-1] + 1;
77                 ++top;
78             }
79         }
80 
81         RMQ_init(top-1);
82         while(m--)
83         {
84             scanf("%d %d",&L,&R);
85             int LI = divide(Num[L],1,top);
86             int RI = divide(Num[R],1,top);
87 
88             if(LI == RI)
89                 printf("%d\n",R-L+1);
90             else
91             {
92                 int MaxNum = Max(Right[LI] - L + 1,R - Left[RI] + 1);
93                 int temp = RMQ(LI+1,RI-1);
94                 printf("%d\n", (Max(temp,MaxNum)) );
95             }
96         }
97     }
98     return 0;
99 }
View Code

 

posted @ 2013-08-20 21:21  好小孩  阅读(123)  评论(0)    收藏  举报