士兵杀敌(三)
时间限制:
2000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。
所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。
现在,请你写一个程序,帮小工回答南将军每次的询问吧。
注意,南将军可能询问很多次。
还是线段树的代码,用c++提交就TLE,用c提交就AC了,坑了好久!!痛苦。
代码如下:
//好坑爹啊!!!把c++改成c就AC了,c++怎么整都是TLE
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
#define MAX 100000
int tmax,tmin;
struct TREE
{
int l,r;
int max,min;
}tree[MAX<<2];
int max (int a,int b)
{
return a > b ? a : b;
}
int min (int a,int b)
{
return a < b ? a : b;
}
void PushUp(int o)
{
tree[o].max = max (tree[o << 1].max,tree[o << 1 | 1].max);
tree[o].min = min (tree[o << 1].min,tree[o << 1 | 1].min);
}
void build(int o,int l,int r)
{
tree[o].l = l;
tree[o].r = r;
if (l == r)
{
scanf ("%d",&tree[o].max);
tree[o].min = tree[o].max;
return;
}
int mid = (l + r) >> 1;
build(o << 1 , l , mid);
build(o << 1 | 1 , mid + 1 , r);
PushUp(o);
}
void Query(int o,int l,int r)
{
if (tree[o].l == l && tree[o].r == r) //如果对应的线段树就是需要寻找的区间,则直接返回值
{
tmax = max(tmax,tree[o].max);
tmin = min(tmin,tree[o].min);
return; //这个return别忘了
}
int mid = (tree[o].l + tree[o].r) >> 1; //否则二分查找
if (mid >= r)
Query (o << 1 , l , r);
else if (l > mid)
Query (o << 1 | 1 , l , r);
else
{
Query(o << 1 , l , mid);
Query(o << 1 | 1 , mid + 1 , r);
}
}
int main()
{
int n,q;
// char op[4];
scanf ("%d %d",&n,&q);
build(1,1,n);
while (q--)
{
int x,y;
scanf ("%d %d",&x,&y);
// strcpy(op,"Max");
// tmax = Query(1,x,y,op);
// strcpy(op,"Min");
// tmin = Query(1,x,y,op); //这么两次搜索线段树会超时
tmax = -1;
tmin = INF;
Query(1,x,y);
printf ("%d\n",tmax-tmin);
}
return 0;
}