1. 程式人生 > >[poj3368]Frequent values(rmq)

[poj3368]Frequent values(rmq)

連續 max 次數 轉化 題意 n) space str ring

題意:給出n個數和Q個詢問(l,r),對於每個詢問求出(l,r)之間連續出現次數最多的次數。

解題關鍵:統計次數,轉化為RMQ問題,運用st表求解,註意邊界。

預處理復雜度:$O(n\log n)$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<iostream>
 7 using namespace std;
 8
typedef long long ll; 9 int a[100002],b[100002]; 10 int min1[100002][22],max1[100002][22],n,q; 11 void rmq(int n){ 12 int lg=int(log10(n)/log10(2)); 13 for(int i=1;i<=n;i++) min1[i][0]=max1[i][0]=b[i]; 14 for(int j=1;j<=lg;j++){ 15 for(int i=1;i+(1<<j)-1<=n;i++){ 16 max1[i][j]=max(max1[i][j-1
],max1[i+(1<<(j-1))][j-1]); 17 //min1[i][j]=min(min1[i][j-1],min1[i+(1<<(j-1))][j-1]); 18 } 19 } 20 } 21 22 int query(int l,int r){ 23 if(l>r) return 0; 24 int k=(int)(log(r-l+1)/log(2.0)); 25 return max(max1[l][k],max1[r-(1<<k)+1][k]); 26
} 27 int main(){ 28 int n,q; 29 while(scanf("%d",&n)!=EOF&&n){ 30 scanf("%d",&q); 31 for(int i=1;i<=n;i++) scanf("%d",a+i); 32 for(int i=1;i<=n;i++){ 33 if(a[i]==a[i-1]) b[i]=b[i-1]+1; 34 else b[i]=1; 35 } 36 rmq(n); 37 while(q--){ 38 int t1,t2,t=0; 39 scanf("%d%d",&t1,&t2); 40 t=t1; 41 while(t<=t2&&a[t]==a[t-1]) t++; 42 int maxres=query(t,t2); 43 maxres=max(maxres,t-t1); 44 printf("%d\n",maxres); 45 } 46 } 47 return 0; 48 }

[poj3368]Frequent values(rmq)