hdu 1806 rmq

找到一个区间内出现最多的数的次数

10 3  //10个数字三次询问
-1 -1 1 1 1 1 3 10 10 10
2 3  
1 10
5 10
0

1
4
3
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=1005;
 9 int n,m;
10 const int MAXN = 100010;
11 int dp[MAXN][20];
12 int mm[MAXN];
13 int a[MAXN],b[MAXN];
14 //初始化RMQ, b数组下标从1开始,从0开始简单修改
15 void makeRMQ(int n,int b[])
16 {
17     for(int i=0;i<n;i++)
18       dp[i][0]=b[i];
19     for(int j=1;(1<<j)<=n;j++)
20       for(int i=0;i+(1<<j)-1<n;i++)
21         dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
22 }
23 int rmq(int s,int v)
24 {
25     int k=(int)(log(v-s+1.0)/log(2.0));
26     return max(dp[s][k],dp[v-(1<<k)+1][k]);
27 }
28 int bi_search(int s,int t)
29 {
30     int tmp=a[t];
31     int l=s;
32     int r=t;
33     int mid;
34     while(l<r)
35     {
36         mid=((l+r)>>1);
37         if(a[mid]>=tmp)r=mid;
38         else l=mid+1;
39     }
40     return r;
41 }
42 int main()
43 {
44     int i,j,k;
45     #ifndef ONLINE_JUDGE
46     freopen("1.in","r",stdin);
47     #endif
48     int q;
49     while(scanf("%d",&n)!=EOF)
50     {
51         if(n==0)    break;
52         scanf("%d",&q);
53         for(i=0;i<n;i++)    scanf("%d",&a[i]);
54         int tmp=1;
55         for(i=n-1;i>=0;i--)
56         {
57             if(i==n-1)  tmp=1;
58             else
59             {
60                 if(a[i]==a[i+1]) tmp++;
61                 else tmp=1;
62             }
63             b[i]=tmp;
64         }
65         makeRMQ(n,b);
66         while(q--)
67         {
68             int s,t;
69             scanf("%d%d",&s,&t);
70             s--,t--;
71             int temp=bi_search(s,t);
72             int ans=t-temp+1;
73             t=temp-1;
74             if(s>t) printf("%d\n",ans); //从s到t的数字都相同
75             else printf("%d\n",max(ans,rmq(s,t)));
76         }
77     }
78 }

 

posted @ 2015-03-23 17:06  miao_a_miao  阅读(131)  评论(0编辑  收藏  举报