题目链接:http://poj.org/problem?id=3264
思路:简单线段树问题,只要标记区间的最大最小值,建树和查询。
#include<iostream> #include<cstdio> using namespace std; #define N 100010 #define L(a) (a)<<1 #define R(a) (a)<<1|1 struct node { int l,r,maxn,minn; }line[3*N]; int num[N],big,small; int mymax(int a,int b) { return a>b?a:b; } int mymin(int a,int b) { return a>b?b:a; } void create(int k,int x,int y) { line[k].l=x;line[k].r=y; if(x==y) { line[k].maxn=line[k].minn=num[x]; return; } int mid=(x+y)>>1; create(L(k),x,mid); create(R(k),mid+1,y); line[k].maxn=mymax(line[L(k)].maxn,line[R(k)].maxn); line[k].minn=mymin(line[L(k)].minn,line[R(k)].minn); } void q(int k,int x,int y) { if(line[k].l==x&&line[k].r==y) { small=mymin(small,line[k].minn); big=mymax(big,line[k].maxn); return; } int mid=(line[k].l+line[k].r)>>1; if(y<=mid) q(L(k),x,y); else if(x>mid) q(R(k),x,y); else { q(L(k),x,mid); q(R(k),mid+1,y); } } int main() { int n,m,i,a,b; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&num[i]); create(1,1,n); for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); big=0;small=1000000000; q(1,a,b); printf("%d\n",big-small); } } return 0; }