http://poj.org/problem?id=3264
初学线段可以做的水题,也是线段树的基础运用。也是我的第一个线段树的题。
题意:在区间范围内的最大值减去最小值
思路:线段树记录下每个区间内的最大值以及最小值,然后查询。
我也是第一次做,然后耗时比较多。
1 #include <stdio.h> 2 #include <string.h> 3 #define maxn 500500 4 5 int max(int x,int y) 6 { 7 return x > y? x : y ; 8 } 9 int min(int x,int y) 10 { 11 return x > y? y : x; 12 } 13 14 struct note{ 15 16 int Min,Max; 17 18 }segtree[ maxn * 2]; 19 20 int arra[ maxn ]; 21 22 23 void build(int root , int arr[] , int instart , int iend) 24 { 25 if(instart == iend) 26 { 27 // segtree[ root ].val = arr[ instart ]; 28 segtree[ root ].Max = arr[ instart ]; 29 segtree[ root ].Min = arr[ instart ]; 30 } 31 else 32 { 33 int mid = (instart+iend)/2; 34 build( root * 2 , arr , instart , mid ); 35 build( root * 2 + 1 , arr , mid + 1 , iend ); 36 segtree[ root ].Max = max(segtree[ root * 2 ].Max,segtree[ root * 2 + 1 ].Max); 37 segtree[ root ].Min = min(segtree[ root * 2 ].Min,segtree[ root * 2 + 1 ].Min); 38 } 39 } 40 41 int remin(int root ,int nstart , int nend , int qstart , int qend) 42 { 43 if(qstart > nend || qend < nstart) 44 return maxn*10; 45 if( qstart <= nstart && qend >= nend ) 46 return segtree[ root ].Min; 47 int mid =( nstart + nend ) / 2; 48 return min(remin(root * 2,nstart,mid,qstart,qend), 49 remin(root * 2 + 1 , mid + 1 , nend , qstart , qend )); 50 } 51 int reMax(int root , int nstart , int nend , int qstart , int qend) 52 { 53 if(qstart > nend || qend < nstart) 54 return 0; 55 if(qstart <= nstart && qend >= nend ) 56 return segtree [ root ].Max; 57 int mid = ( nstart + nend ) / 2; 58 return max(reMax(root * 2, nstart , mid , qstart , qend ), 59 reMax(root * 2 + 1 , mid + 1 , nend , qstart , qend ) ); 60 } 61 62 int main() 63 { 64 // freopen("in.txt","r",stdin); 65 int m,n,a,b,ma,mi; 66 scanf("%d%d",&m,&n); 67 for( int i = 1 ; i <= m ; i++ ) 68 scanf("%d",&arra[ i ]); 69 build(1,arra,1,m); 70 while(n--) 71 { 72 scanf("%d%d",&a,&b); 73 ma = reMax(1,1,m,a,b); 74 mi = remin(1,1,m,a,b); 75 printf("%d\n",ma-mi); 76 } 77 return 0; 78 }
时间: 2024-11-03 22:01:54