动态规划解决方案, #include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; const int maxn=50005; const int maxi=17; int height[maxn]; int min_height[maxn][maxi]; int max_height[maxn][maxi]; int M,N; //void Print(int min_left,int min_right) //{ // cout<<"min_height:/n"; // for(int i = 1; i <= min_left; i++) // { // for(int j = 0; j < min_right; j++) // cout<<min_height[i][j]<<" "; // cout<<endl; // } // cout<<"max_height:/n"; // for(int i = 1; i <= min_left; i++) // { // for(int j = 0; j < min_right; j++) // cout<<max_height[i][j]<<" "; // cout<<endl; // } // cout<<endl; //} void dp() { for(int i = 1; i <= M; i++) { min_height[i][0] = height[i]; max_height[i][0] = height[i]; } int level = log(M)/log(2) + 1; for( int i = 1; i < level; i++) { for( int j = 1 ; j <= M ; j++) { int mid = j + (1<<(i-1)) ; if(mid > M) break; max_height[j][i] = max(max_height[j][i-1],max_height[mid][i-1]) ; min_height[j][i] = min(min_height[j][i-1],min_height[mid][i-1]) ; } } } void search(int left,int right) { int level = log( right - left + 1) /log(2); int min_result = min(min_height[left][level],min_height[ right+1 - (1<<(level)) ][level]); int max_result = max(max_height[left][level],max_height[ right+1 - (1<<(level)) ][level]); printf("%d/n",max_result - min_result); } int main() { scanf("%d%d",&M,&N); for(int i = 1; i <= M; i++ ) scanf("%d",height+i); dp(); int left,right; for(int i = 1; i <= N; i++) { scanf("%d%d",&left,&right); search(left,right); } } 线段树解决方案 /* 线段树求解 */ #include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; const int maxn = 50005; struct node{ int m_left; int m_right; int m_min; int m_max; }; struct node data[3*maxn]; int min_result = 0; int max_result = 1<<30; int height[maxn]; int M,N; int ind_height = 1; void create(int ind, int left, int right) { data[ind].m_left = left; data[ind].m_right = right; if( left == right) { data[ind].m_max = data[ind].m_min = height[ind_height]; ind_height++; // cout<<"only"<<ind<<endl; return; } int mid = (right +left)>>1; create(ind*2 ,left,mid); create(ind*2 +1,mid+1,right); data[ind].m_max = max( data[ind*2].m_max, data[ind*2+1].m_max); data[ind].m_min = min( data[ind*2].m_min, data[ind*2+1].m_min); // cout<<ind<<endl; } void Print() { for( int i = 1; i <= 3*M ; i++) cout<<data[i].m_max<<" "<<data[i].m_min<<data[i].m_left<<data[i].m_right<<endl; } void Find(int ind_node, int left,int right) { if(left <= data[ind_node].m_left && right >= data[ind_node].m_right) { if( max_result < data[ind_node].m_max ) max_result = data[ind_node].m_max; if( min_result > data[ind_node].m_min ) min_result = data[ind_node].m_min; return ; } if( data[ind_node].m_left == data[ind_node].m_right) return ; //if(left >= data[ind_node].m_right ) if(left <= data[ind_node*2].m_right) Find(ind_node*2,left,right); if(right >= data[ind_node*2+1].m_left ) Find(ind_node*2+1,left,right); } int main() { scanf("%d%d",&M,&N); for(int i = 1; i <= M; i++ ) scanf("%d",height+i); //cout<<endl; create(1,1,M); //Print(); // cout<<ind_height; // cout<<endl; // cout<<endl; int left,right; for(int i = 1; i <= N; i++) { min_result = 1<<30; max_result = 0; scanf("%d%d",&left,&right); Find(1,left,right); printf("%d/n",max_result-min_result); } }