POJ 3246 Balanced Lineup

题目链接: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;
}


你可能感兴趣的:(struct)