题目大意是给出一个非降序排列的数组,然后n个询问,每次询问一个区间内出现次数最多的数的次数。

首先要弄清楚题目的是一个非降序的数组,那么说明相等的数都会在一起,类似于11223334569这样的,那么可以将其合并,由于这种多次区间询问的题一般用

到的是线段树或者RMQ,所以就往这方面去靠,用num[i]和cont[i]表示第i段的数值和出现的次数,val[i]表示位置i所在段的编号,lef[i]和ri[i]表示位置i所在段的左右端点

位置,那么对于每次查询(l,r)区间就分成了三段,ri[l]-l+1,r-lef[r]+1和中间一段,而中间的一段就完全是根据cont数组求的RMQ问题,然后三者取大的就好。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int M = 1e5 + 10;
 8 int a[M],d[M][20],cont[M],num[M];
 9 int lef[M],ri[M],val[M];
10 int max(int x,int y) {return x>y?x:y;}
11 
12 void rmq(int x)
13 {
14     for (int i=1 ; i<=x ; i++) d[i][0]=cont[i];
15     for (int j=1 ; (1<<j)<=x ; j++)
16         for (int i=0 ; i+(1<<j)-1<x ; i++)
17            d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
18 }
19 
20 int rmq(int l,int r)
21 {
22     if (l>r) return 0;
23     int k=0;
24     while ((1<<(k+1))<=r-l+1) k++;
25     return max(d[l][k],d[r-(1<<k)+1][k]);
26 }
27 
28 int main()
29 {
30     int n,q,i;
31     while (~scanf("%d",&n)&&n){
32     scanf("%d",&q);
33     for (i=1 ; i<=n ; i++) scanf("%d",a+i);
34     int ans=-M,j=1;
35     memset(cont,0,sizeof(cont));
36     for (i=1 ; i<=n ; i++)
37     {
38         if (a[i]!=ans)
39         {
40             val[j]=a[i];
41             ans=a[i];
42             int k=i,w=i;
43             while (ans==a[i]){
44                 cont[j]++;
45                 i++;
46             }
47             i--;
48             for ( ; k<=i ; k++)
49             {
50                 num[k]=j;
51                 lef[k]=w;
52                 ri[k]=i;
53             }
54             j++;
55         }
56     }
57     j--;
58     rmq(j);
59     int l,r;
60    /* for (i=1 ; i<=j ; i++) cout<<val[i]<<" ";
61     cout<<endl;
62     for (i=1 ; i<=j ; i++) cout<<cont[i]<<" ";
63     cout<<endl;
64     for (i=1 ; i<=n ; i++) cout<<num[i]<<" ";
65     cout<<endl;
66     for (i=1 ; i<=n ; i++) cout<<lef[i]<<" ";
67     cout<<endl;
68     for (i=1 ; i<=n ; i++) cout<<ri[i]<<" ";
69     cout<<endl;*/
70     while (q--)
71     {
72         scanf("%d%d",&l,&r);
73         if (num[l]==num[r])
74         {
75             printf("%d\n",r-l+1);
76             continue;
77         }
78         printf("%d\n",max(r-lef[r]+1,max(rmq(num[ri[l]+1],num[lef[r]-1]),ri[l]-l+1)));
79 
80     }
81     }
82     return 0;
83 }

 

 

posted on 2016-04-26 15:43  蜘蛛侦探  阅读(207)  评论(0编辑  收藏  举报