UVA 11235 求區間連續數的眾數 RMQ
阿新 • • 發佈:2019-01-29
題意:
給定n長的序列, query次詢問
下面n個數表示詢問
對於每次詢問的區間,回答該區間連續相同的數 這樣的段最長有多長
思路:
RMQ裸題
特判下左右端點然後中間部分RMQ即可
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> using namespace std; const int MAXN = 100100; int n,query; int A[MAXN]; int FMin[MAXN][20],FMax[MAXN][20]; void Init(){ int i,j; for(i=1;i<=n;i++) FMin[i][0]=FMax[i][0]=A[i]; for(i=1;(1<<i)<=n;i++){ //按區間長度遞增順序遞推 for(j=1;j+(1<<i)-1<=n;j++){ //區間起點 FMin[j][i]=min(FMin[j][i-1],FMin[j+(1<<(i-1))][i-1]); FMax[j][i]=max(FMax[j][i-1],FMax[j+(1<<(i-1))][i-1]); } } } int Query(int l,int r){ int k=(int)(log(double(r-l+1))/log((double)2)); return max(FMax[l][k],FMax[r-(1<<k)+1][k]); } int num[MAXN], l[MAXN], r[MAXN]; int main(){ int i,j,a,b; while(scanf("%d",&n), n){ scanf("%d",&query); int cnt = 1; int L = 1, R = 1; for(i=1;i<=n;i++) { scanf("%d",&num[i]); if(num[i] == num[i-1] && i!=1) { R++; cnt++; } if((i!=1 && num[i]!=num[i-1]) || i==n) { for(j = L; j <= R; j++) { A[j] = cnt; l[j] = L; r[j] = R; } cnt = 1; L = R = i; } } for(j = L; j <= n; j++)A[j] = cnt, l[j] = L, r[j] = n; Init(); while(query--) { scanf("%d %d",&a,&b); if(a>b)swap(a,b); L = r[a]; if(L>=b){printf("%d\n", b-a+1);continue;} R = l[b]; if(R<=a){printf("%d\n", b-a+1);continue;} int ans = max(L-a+1, b-R+1); if(L == R-1){printf("%d\n", ans);continue;} L++, R--; printf("%d\n", max( ans, Query(L,R))); } } return 0; } /* 8 4 -1 -1 1 1 1 1 3 10 2 3 1 1 8 8 1 8 1 1 1 1 1 2 3 1 2 1 1 1 2 2 2 0 */