#include <bits/stdc++.h> using namespace std; int n,q,a[1005][1005];//a[i][j]代表从i开始 长度为2^j的区间内最大的 int que(int l,int r){ int k=log2(r-l+1); //k是最小的 可以包含整个区间的 长度 //用两个等长的小区间 覆盖一个大区间 return max(a[l][k],a[r-(1<<k)+1][k]); //两区域可有重叠 } int main(){ int T,l,r; cin>>T; while(T--){ cin>>n; for(int i=1;i<=n;i++){ scanf("%d",&a[i][0]); } for(int j=1;j<=21;j++) for(int i=1;i+(1<<j)-1<=n;i++){ a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]); //正好分成前后两半 } cin>>q; while(q--){ scanf("%d%d",&l,&r); printf("%d\n",que(l,r)); } } } //移位要加括号 !!
与树链剖分一样 掌握树链剖分即可