题目链接:http://acm.tju.edu.cn/toj/showp2762.html
Time Limit: 5.0 Seconds Memory Limit: 65536K
Total Runs: 1458 Accepted Runs: 544 Multiple test files
Farmer John has made a list of Q (1 ≤ Q ≤ 180,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.
Note: on the largest test case, I/O takes up the majority of the runtime.
Input
* Line 1 : Two space-separated integers, N and Q.
* Lines 2 .. N + 1 : Line i + 1 contains a single integer that is the height of cow i
* Lines N + 2 .. N + Q + 1: Two integers A and B ( 1 ≤ A ≤ B ≤ N ), representing the range of cows from A to B inclusive.
Output
* Lines 1 .. Q : Each line contains a single integer that is an answer to an input query and tells the difference in height between the tallest and shortest cow in the input range.Sample Input
6 3 1 7 3 4 2 5 1 5 4 6 2 2
Sample Output
6 3 0
Source: USACO 2007 January Competition
作者:kuangbin(转载请注明出处,谢谢!!)
更多详细文章,请访问博客:www.cnblogs.com/kuangbin
ACM POJ 3264 Balanced Lineup
这到题目是线段树的练习题目。
很简单,练练手!!
AC程序:
/* POJ 3264 Balanced Lineup 题目意思:给定Q(1<=Q<=200000)个数A1,A2,```,AQ, 多次求任一区间Ai-Aj中最大数和最小数的差 */ #include<stdio.h> #include<algorithm> #include<iostream> using namespace std; #define MAXN 200005 #define INF 10000000 int nMax,nMin;//记录最大最小值 struct Node { int l,r;//区间的左右端点 int nMin,nMax;//区间的最小值和最大值 }segTree[MAXN*3]; int a[MAXN]; void Build(int i,int l,int r)//在结点i上建立区间为(l,r) { segTree[i].l=l; segTree[i].r=r; if(l==r)//叶子结点 { segTree[i].nMin=segTree[i].nMax=a[l]; return; } int mid=(l+r)>>1; Build(i<<1,l,mid); Build(i<<1|1,mid+1,r); segTree[i].nMin=min(segTree[i<<1].nMin,segTree[i<<1|1].nMin); segTree[i].nMax=max(segTree[i<<1].nMax,segTree[i<<1|1].nMax); } void Query(int i,int l,int r)//查询结点i上l-r的最大值和最小值 { if(segTree[i].nMax<=nMax&&segTree[i].nMin>=nMin) return; if(segTree[i].l==l&&segTree[i].r==r) { nMax=max(segTree[i].nMax,nMax); nMin=min(segTree[i].nMin,nMin); return; } int mid=(segTree[i].l+segTree[i].r)>>1; if(r<=mid) Query(i<<1,l,r); else if(l>mid) Query(i<<1|1,l,r); else { Query(i<<1,l,mid); Query(i<<1|1,mid+1,r); } } int main() { int n,q; int l,r; int i; while(scanf("%d%d",&n,&q)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); Build(1,1,n); for(i=1;i<=q;i++) { scanf("%d%d",&l,&r); nMax=-INF;nMin=INF; Query(1,l,r); printf("%d\n",nMax-nMin); } } return 0; }
另外附一参考程序:
#include <iostream> #include <algorithm> #include <numeric> using namespace std; #define MY_MIN 99999999 #define MY_MAX -99999999 struct CNode { int L,R; int nMin,nMax; CNode * pLeft, * pRight; }; int nMax, nMin; CNode Tree[1000000]; //CNode Tree[20]; int nCount = 0; void BuildTree(CNode * pRoot, int L,int R) { pRoot->L = L; pRoot->R = R; pRoot->nMin = MY_MIN; pRoot->nMax = MY_MAX; if ( L != R) { nCount ++; pRoot->pLeft = Tree + nCount; nCount ++; pRoot->pRight = Tree + nCount; BuildTree( pRoot->pLeft, L, ( L + R )/2); BuildTree( pRoot->pRight, (L + R) / 2 + 1,R); } } void Insert( CNode * pRoot , int i,int v) { if( pRoot->L == i && pRoot->R == i ) { pRoot->nMin = pRoot->nMax = v; return; } pRoot->nMin = _cpp_min(pRoot->nMin,v); pRoot->nMax = _cpp_max(pRoot->nMax,v); if( i <= (pRoot->L + pRoot->R )/2 ) Insert( pRoot->pLeft,i,v); else Insert( pRoot->pRight,i,v); } void Query(CNode * pRoot, int s, int e) { if( pRoot->nMin >= nMin && pRoot->nMax <= nMax ) return; if( s == pRoot->L && e == pRoot->R) { nMin = _cpp_min(pRoot->nMin,nMin); nMax = _cpp_max(pRoot->nMax,nMax); return ; } if( e <= (pRoot->L + pRoot->R) / 2 ) Query(pRoot->pLeft, s,e); else if( s >= (pRoot->L + pRoot->R) / 2 + 1) Query(pRoot->pRight, s,e); else { Query(pRoot->pLeft, s,(pRoot->L + pRoot->R) / 2); Query(pRoot->pRight, (pRoot->L + pRoot->R) / 2 + 1 ,e); } } int main() { int n,q,h; int i,j,k; scanf("%d%d",&n,&q); nCount = 0; BuildTree(Tree,1,n); for( i = 1;i <= n;i ++ ) { scanf("%d",&h); Insert( Tree,i,h); } for( i = 0;i < q;i ++ ) { int s,e; scanf("%d%d", &s,&e); nMax = MY_MAX; nMin = MY_MIN; Query(Tree,s,e); printf("%d\n",nMax - nMin); } return 0; }