您的位置:首页 > 其它

【CF52C】Circular RMQ(线段树区间加减,区间最值)

2016-05-23 20:38 274 查看

给定一个循环数组a0, a1, a2, …, an-1,现在对他们有两个操作:

Inc(le, ri, v)表示区间[le, ri]范围的数值增加v

Rmq(le, ri)表示询问区间[le, ri]范围内的最小值

注意,这个是循环数组,所以如果n=5, le=3, ri=1,那么询问的是a3, a4, a0, a1中的最小值。

帮助BSNY写一个程序完成上述操作。

【数据规模和约定】

 

1<= n <=200000   0<=Q<=200000


-10^6<= ai <=10^6   0<=le, ri<=n-1   -10^6<= v <=10^6

 

简单的线段树区间加减,区间求最值。

注意max已经超过maxlongint

 

 

const oo=1000000000000000000;
var tree:array[1..1000000]of record
a,s:int64;
end;
a:array[1..1000000]of int64;
n,q,len,x,y,z,p:int64;
ch,s:string;
i,j,k:longint;

procedure pushdown(p:int64);
begin
tree[p<<1].s:=tree[p<<1].s+tree

.a; tree[p<<1].a:=tree[p<<1].a+tree[p].a; tree[p<<1+1].s:=tree[p<<1+1].s+tree[p].a; tree[p<<1+1].a:=tree[p<<1+1].a+tree[p].a; tree[p].a:=0; end; procedure pushup(p:int64); begin if tree[p<<1].s<tree[p<<1+1].s then tree[p].s:=tree[p<<1].s else tree[p].s:=tree[p<<1+1].s; // tree[p].s:=min(tree[p<<1].s,tree[p<<1+1].s); end; procedure build(l,r,p:int64); var mid:int64; begin if l=r then begin tree[p].s:=a[l]; tree[p].a:=0; exit; end; mid:=(l+r)>>1; if l<=mid then build(l,mid,p<<1); if r>mid then build(mid+1,r,p<<1+1); pushup(p); end; function query(l,r,x,y,p:int64):int64; var mid:int64;t,ret:int64; begin if (x<=l)and(y>=r) then exit(tree[p].s); pushdown(p); mid:=(l+r)>>1; ret:=oo; //query:=oo; if x<=mid then ret:=query(l,mid,x,y,p<<1); if y>mid then begin t:=query(mid+1,r,x,y,p<<1+1); if t<ret then ret:=t; //query:=min(query,t); end; exit(ret); end; procedure update(l,r,x,y,v,p:int64); var mid:int64; begin if (x<=l)and(y>=r) then begin tree[p].s:=tree[p].s+v; tree[p].a:=tree[p].a+v; exit; end; pushdown(p); mid:=(l+r)>>1; if x<=mid then update(l,mid,x,y,v,p<<1); if y>mid then update(mid+1,r,x,y,v,p<<1+1); pushup(p); end; begin readln(n); for i:=1 to n do read(a[i]); for i:=1 to n<<2 do tree[i].s:=oo; build(1,n,1); readln(q); for i:=1 to q do begin readln(ch); len:=length(ch); p:=0; for j:=1 to len do if ch[j]=' ' then inc(p); if p=1 then begin x:=0; j:=0; repeat inc(j); if ch[j]<>' ' then x:=x*10+ord(ch[j])-ord('0') else break; until j=len; y:=0; repeat inc(j); if ch[j]<>' ' then y:=y*10+ord(ch[j])-ord('0') else break; until j=len; inc(x); inc(y); if x<=y then writeln(query(1,n,x,y,1)) else if query(1,n,x,n,1)<query(1,n,1,y,1) then writeln(query(1,n,x,n,1)) else writeln(query(1,n,1,y,1)); end else begin x:=0; j:=0; repeat inc(j); if ch[j]<>' ' then x:=x*10+ord(ch[j])-ord('0') else break; until j=len; y:=0; repeat inc(j); if ch[j]<>' ' then y:=y*10+ord(ch[j])-ord('0') else break; until j=len; s:=''; for k:=j+1 to len do s:=s+ch[k]; val(s,z); inc(x); inc(y); if x<=y then update(1,n,x,y,z,1) else begin update(1,n,x,n,z,1); update(1,n,1,y,z,1); end; end; end; end.

[p] 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: