jzoj1278 排隊(線段樹)

2021-08-03 12:58:41 字數 2945 閱讀 2750

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 xthen

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.

JZOJ 4811 排隊 線段樹的方法

關鍵是操作1。我們要將order前面x個空的房間補滿。我們盡量往左補,如果能夠補完就補,不能補完就往右補直到補完為止。void modify int s,int l,int r,int x,bool p int wz l r 2,prd tree s 2 if prd x 左邊有空位 modify ...

bzoj2141 排隊(線段樹 splay)

題目鏈結 分析 之所以找到這道題是因為不想寫dp了 看到網上的題解都是 分塊 線段樹,樹狀陣列 線段樹。立志自己想解法 一開始我在想,能不能用cdq搞 但是cdq版的動態逆序對好像是單點修改 實際上逆序對的個數就是每個數字形成的逆序對之和 而每個數會和在ta之前比ta大的數以及在ta之後比ta大的數...

bzoj3333 排隊計畫 (線段樹)

time limit 20 sec memory limit 128 mb submit 717 solved 323 submit status discuss 6 2160 163 164 161 167 160 2 3 63 1 題目思路 每次操作是把乙個數後面所有小於等於該數值的位置都排序重...