Frequent values[RMQ]

题目:

Frequent values[RMQ]

 题意:给一个长度为n的非降序的数组,询问q次,问[L,R]内出现最多的数字的出现次数。

 思路:因为数组是非降序的,相同的数字会聚集到一起,可以进行离散化,用cnt[i]表示第i段数字一共出现的次数,num[p]表示 p位置的编号,lft[p]表示p位置的数字的最左位置,rit[p]同理。那么对于每个查询[L,R],最大值应该是三个部分:L到rit[L],lft[R]到R,以及从rit[L]+1到lft[R]-1中的最大值。这是一个不需要修改的区间最值查询,用ST可做。

 1 #include<bits/stdc++.h>
 2 #define fi first
 3 #define se second
 4 #define pb(i) push_back(i)
 5 #define rep(i,a,b) for(int i=a;i<=b;i++)
 6 #define per(i,a,b) for(int i=b;i>=a;i--)
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define VI vector<int>
 9 #define VLL vector<ll>
10 #define MPII map<pair<int,int>,int>
11 #define mp make_pair
12 #define PQI priority_queue<int>
13 using namespace std;
14 typedef long long ll;
15 typedef unsigned long long ull;
16 const int N = 1e6+10;
17 const int INF = 0x3f3f3f3f;
18 const int inf = - INF;
19 const int mod = 1e9+7;
20 const double pi = acos(-1.0);
21 const double eps=1e-5;
22 int n,pos=0;
23 int value[N],cnt[N];
24 int num[N];
25 int lft[N],rit[N];
26 int d[N][30];
27 void RMQ_init(){
28     memset(d,0,sizeof(d));
29     for(int i=0;i<=pos;i++) d[i][0]=cnt[i];
30     for(int j=1;(1<<j)<=pos;j++){
31         for(int i=1;i+(1<<j)-1<=pos;i++)
32             d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
33     }
34 }
35 int RMQ(int l,int r){
36     int ans=0;
37     if(num[l]==num[r]) return r-l+1;
38     ans=max(ans,max(rit[l]-l+1,r-lft[r]+1));
39     int k=0;
40     int L=rit[l]+1,R=lft[r]-1;
41     if(num[L]>num[R]) return ans;//中间没有其他数字
42     if(num[L]==num[R]) return max(ans,R-L+1);
43     while(1<<(k+1)<=num[R]-num[L]+1) k++;
44     return max(ans,max(d[num[L]][k],d[num[R]-(1<<k)+1][k]));
45 }
46 //vector<int>a;
47 int a[N];
48 int main(){
49     int q;
50     while(scanf("%d",&n)==1&&n){
51         scanf("%d",&q);
52         pos=0;
53         memset(num,0,sizeof(num));
54         memset(value,0,sizeof(value));
55         memset(lft,0,sizeof(lft));
56         memset(rit,0,sizeof(rit));
57         memset(cnt,0,sizeof(cnt));
58         a[0]=inf;
59         for(int i=1;i<=n;i++){
60             scanf("%d",&a[i]);
61             if(a[i]!=a[i-1]){
62                 value[++pos]=a[i];
63                 cnt[pos]++;
64                 lft[i]=i;
65             }
66             else{
67                 cnt[pos]++;
68                 lft[i]=lft[i-1];
69             }
70             num[i]=pos;
71         }
72         for(int i=1;i<=n;i++)
73             rit[i]=lft[i]+cnt[num[i]]-1;
74         RMQ_init();
75         while(q--){
76             int l,r;
77             scanf("%d%d",&l,&r);
78             printf("%d
",RMQ(l,r));
79         }
80     }
81     system("pause");
82     return 0;
83 }