poj 2019 Cornfields
二位线段树:
View Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<cstring> #include<vector> #include<string> #define LL long long using namespace std; class Node { public: int l,r,max,min; }; class Tree { public: int l,r; Node n[1024]; }T[1024]; int Max,Min; int map[254][254]; void build_y( Node *p ,int l , int r , int cnt , int s,int e ) { // printf( "l==%d r==%d\n",l,r ); p[cnt].l = l ;p[cnt].r = r; if( l == r ) { int MAX = -1,MIN = 0x7fffffff; for( int i = s ; i <= e ; i ++ ) { MAX = max( MAX , map[i][l] ); MIN = min( MIN , map[i][l] ); } p[cnt].min = MIN ;p[cnt].max = MAX; return; } int mid = ( l + r )>>1; build_y( p , l , mid ,cnt*2,s,e ); build_y( p , mid + 1 , r , cnt*2+1,s,e ); p[cnt].max = max( p[cnt*2].max , p[cnt*2+1].max ); p[cnt].min = min( p[cnt*2].min , p[cnt*2+1].min ); // printf( "%d %d %d %d\n",l,r,p[cnt].max , p[cnt].min ); } void build( int l, int r , int cnt , int N ) { T[cnt].l = l ; T[cnt].r = r; build_y( T[cnt].n ,1 , N , 1 ,l ,r ); if( l == r ) return; int mid = ( l + r )>>1; build( l , mid , cnt*2 , N ); build( mid + 1 , r , cnt*2+1 , N ); } void Query_y( Node *p ,int l, int r , int cnt ) { // printf( "af" ); if( l <= p[cnt].l && r >= p[cnt].r ) { Max = max( Max , p[cnt].max ); Min = min( Min , p[cnt].min ); return; } int mid = ( p[cnt].l + p[cnt].r )>>1; if( mid >= r ) Query_y( p , l ,r ,cnt*2 ); else if( mid < l ) Query_y( p , l , r , cnt* 2 + 1 ); else { Query_y( p , l , mid , cnt*2 ); Query_y( p , mid + 1, r , cnt*2 + 1 ); } } void Query( int l , int r , int cnt ,int y1 , int y2 ) { // printf( "%d %d %d %d %d\n",l,r,cnt,T[cnt].l,T[cnt].r ); if( l<=T[cnt].l&&r >= T[cnt].r ) {//printf( "af" ); Query_y( T[cnt].n ,y1, y2 ,1 ); return ; } int mid = ( T[cnt].l + T[cnt].r )>>1; if( mid >= r ) Query( l , r , cnt*2 , y1 , y2 ); else if( mid < l ) Query( l , r, cnt * 2 + 1, y1, y2 ); else { Query( l , mid , cnt*2 , y1 ,y2 ); Query( mid + 1 , r , cnt*2 +1 , y1 , y2 ); } } int main( ) { int N,B,K,R,L; while( scanf( "%d %d %d",&N,&B,&K )==3 ) { for( int i = 1; i <= N; i ++ ) for( int j = 1 ; j <= N; j ++ ) scanf( "%d",&map[i][j] ); build( 1 , N ,1 ,N ); for( int i = 0 ; i < K ; i++ ) { Max = -1 ; Min = 0x7ffffff; scanf( "%d %d",&R,&L ); Query( R , R + B -1, 1 , L , L + B-1 ); // printf( "%d %d\n",Max ,Min ); printf( "%d\n",Max - Min ); } } //system( "pause" ); return 0; }