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\n",RMQ(l,r)); 79 } 80 } 81 system("pause"); 82 return 0; 83 }