UVa 11235 RMQ
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 100000 + 100; const int maxlog = 20; int a[maxn],num[maxn],Left[maxn],Right[maxn]; int counts[maxn]; int n,q; int segcnt; struct RMQ { int d[maxn][maxlog]; void init() { memset(d,-0x3f,sizeof(d)); for(int i=1; i<=segcnt; i++) d[i][0] = counts[i]; for(int j=1; (1<<j)<=segcnt; j++) for(int k=1; k+(1<<(j-1)) <= segcnt; k++) d[k][j] = max(d[k][j-1],d[k+(1<<(j-1))][j-1]); } int query(int L,int R) { int k = 0; while( (1<<(k+1)) <= R-L+1 ) k++; return max(d[L][k],d[R-(1<<k)+1][k]); } }solver; int main() { //freopen("E:\\acm\\input.txt","r",stdin); while(cin>>n && n) { cin>>q; for(int i=1; i<=n; i++) scanf("%d",&a[i]); segcnt = 0; for(int i=1; i<=n; i++) { num[i] = ++segcnt; Left[i] = i; counts[segcnt] = 1; for(int j=i+1; j<=n+1; j++) { if(j == n+1) { i = n+1; break; } if(a[j] != a[i]) { for(int k=i; k<j; k++) Right[k] = j-1; i = j-1; break; } counts[segcnt]++; Left[j] = i; num[j] = segcnt; } } solver.init(); while(q--) { int l,r; scanf("%d %d",&l,&r); if(num[l] == num[r]) printf("%d\n",r-l+1); else { int ans = max(Right[l]-l+1,r-Left[r]+1); if(num[l]+1 < num[r]) { ans = max(ans,solver.query(num[l]+1,num[r]-1)); } printf("%d\n",ans); } } } }