poj 3368 Frequent values

题目给出了一个非下降序列,求给定的一个区间内重复个数最多是多少。

这题可以用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 }
posted @ 2012-08-17 23:26  發_  阅读(124)  评论(0编辑  收藏  举报