大白书上的例题,具体讲解见大白书,最好用用一个Log数组直接求k,这样就是纯O(1)了

#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 100003 int a[N],num[N],le[N],ri[N],cnt[N]; int d[N][21],n,type; void RMQ_init() { int i,j; for(i=1;i<=type;i++) d[i][0] = cnt[i]; for(j=1;(1<<j)<=type;j++) { for(i=1;i+(1<<j)-1<=type;i++) d[i][j] = max(d[i][j-1],d[i+(1<<(j-1))][j-1]); } } int LOG[50007]; void getLog(int n) { for(int i=0;i<=n;i++) LOG[i] = (int)(log((double)i)/log(2.0)); } int RMQ(int l,int r) { int k = LOG[R-L+1]; return max(d[l][k],d[r-(1<<k)+1][k]); } int main() { int q,i,j,pos; int l,r; while(scanf("%d",&n)!=EOF && n) { scanf("%d",&q); for(i=1;i<=n;i++) scanf("%d",&a[i]); a[0] = -1000000; type = 0; for(pos=1;pos<=n;pos++) { if(a[pos] != a[pos-1]) { if(pos != 1 ) cnt[type] = pos-le[pos-1]; num[pos] = ++type; for(j=le[pos-1];j<=pos-1;j++) ri[j] = pos-1; le[pos] = pos; if(pos == n) cnt[type] = 1,ri[pos] = pos; } else { le[pos] = le[pos-1]; num[pos] = num[pos-1]; if(pos == n) { cnt[type] = pos - le[pos] + 1; for(j=le[pos];j<=n;j++) ri[j] = n; } } } RMQ_init(); while(q--) { scanf("%d%d",&l,&r); if(num[l] == num[r]) { printf("%d ",r-l+1); continue; } int lmax = ri[l]-l+1; int rmax = r-le[r]+1; int mmax; if(num[l]+1 > num[r]-1) mmax = 0; else mmax = RMQ(num[l]+1,num[r]-1); printf("%d ",max(mmax,max(lmax,rmax))); } } return 0; }