jzoj1278 排队(线段树)

来源:互联网 发布:手机配件淘宝加盟 编辑:程序博客网 时间:2024/05/22 15:24
1278. 排队 


Description


  每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛.但是为了避免水平悬殊,牛的身高不应该相差太大.
  John 准备了Q (1 <= Q <= 180,000) 个可能的牛的选择和所有牛的身高 (1 <=身高 <= 1,000,000). 他想知道每一组里面最高和最低的牛的身高差别.


Input


  第一行: N 和 Q.
  第2..N+1行: 第i+1行是第i头牛的身高.
  第N+2..N+Q+1行: 两个整数, A 和 B (1 <= A <= B <= N), 表示从A到B的所有牛.


Output


  第1..Q行: 所有询问的回答 (最高和最低的牛的身高差), 每行一个.


分析:线段树维护max,min。


代码

const  maxn=500000;type  arr=record    l,r,max,min:longint;end;var  tree:array[0..maxn] of arr;  a:array[0..maxn] of longint;  h,t,p,q,a1,a2,n,m,i:longint;  fl:boolean;function maxf(x,y:longint):longint;begin  if x>y then exit(x) else exit(y);end;function minf(x,y:longint):longint;begin  if x<y then exit(x) else exit(y);end;procedure build(p:longint);var  mi:longint;begin  if tree[p].l=tree[p].r then    begin      tree[p].max:=a[tree[p].l];      tree[p].min:=a[tree[p].r];      exit;    end;  mi:=(tree[p].l+tree[p].r) div 2;  tree[p*2].l:=tree[p].l;  tree[p*2].r:=mi;  tree[p*2+1].l:=mi+1;  tree[p*2+1].r:=tree[p].r;  build(p*2);  build(p*2+1);  tree[p].max:=maxf(tree[p*2].max,tree[p*2+1].max);  tree[p].min:=minf(tree[p*2].min,tree[p*2+1].min);end;procedure find1(x,p,q:longint);var  mi:longint;begin  mi:=(tree[x].l+tree[x].r) div 2;  if (tree[x].l=p) and (tree[x].r=q)    then a1:=maxf(a1,tree[x].max)    else begin           if (tree[x].l=tree[x].r) then exit;           if q<=mi             then find1(x*2,p,q)             else if p>=mi+1               then find1(x*2+1,p,q)               else begin                      find1(x*2,p,mi);                      find1(x*2+1,mi+1,q);                    end;         end;end;procedure find2(x,p,q:longint);var  mi:longint;begin  mi:=(tree[x].l+tree[x].r) div 2;  if (tree[x].l=p) and (tree[x].r=q)    then a2:=minf(a2,tree[x].min)    else begin           if (tree[x].l=tree[x].r) then exit;           if q<=mi             then find2(x*2,p,q)               else if p>=mi+1                  then find2(x*2+1,p,q)                 else begin                        find2(x*2,p,mi);                        find2(x*2+1,mi+1,q);                      end;           end;end;begin  readln(n,m);  for i:=1 to n do    readln(a[i]);  tree[1].l:=1;  tree[1].r:=n;  build(1);  for i:=1 to m do    begin      readln(h,t);      a1:=0;      a2:=maxlongint;      find1(1,h,t);      find2(1,h,t);      writeln(a1-a2);    end;end.

阅读全文
0 0