tips:
1.位运算--左移k位==乘以2^k
2.+-的优先级高于<<
3.dp自底向上求解
4.数组大小第二维log(n)
5.ref:紫书P197和度娘的ppt
//有点归并排序的味道,分治两两合并,不过是自底向上 //#include<bits/stdc++.h> //多重循环嵌套想想意义就好理解哪个变量为什么应该在外层 #include<cstdio> #include<algorithm> using namespace std; const int M=50010; int dMin[M][20]; int dMax[M][20]; int n,q; int a[M]; int L,R; void RMQ_min_init(int a[]){ for(int i=1;i<=n;i++) dMin[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++){//区间长度 for(int i=1;i+(1<<j)-1<=n;i++){ dMin[i][j]=min(dMin[i][j-1],dMin[i+(1<<j-1)][j-1]);//减号的优先级高于位运算 } } } int RMQ_min_Q(int L, int R){ int k=0; while((1<<(k+1))<= (R-L+1)) k++; return min(dMin[L][k],dMin[R-(1<<k)+1][k]); } void RMQ_max_init(int a[]){ for(int i=1;i<=n;i++) dMax[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1 <= n; i++)//防止数组越界 dMax[i][j]=max(dMax[i][j-1],dMax[i+(1<<(j-1))][j-1]); } int RMQ_max_Q(int L,int R){ int k=0; while((1<<k+1)<= (R-L+1)) k++; return max(dMax[L][k],dMax[R-(1<<k)+1][k]); } int main(){ while(scanf("%d%d",&n,&q)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } RMQ_min_init(a); RMQ_max_init(a); for(int i=0;i<q;i++){ scanf("%d%d",&L,&R); int ans1=RMQ_min_Q(L,R); int ans2=RMQ_max_Q(L,R); printf("%d\n",ans2-ans1); } } return 0; }
//https://wenku.baidu.com/view/57c9a018ff4733687e21af45b307e87100f6f87f.html