tyvj 1039忠诚2——初识线段树
分析:显然是一个线段树,不解释
至于具体的实现过程。。。稍说明一下
线段树的原理,就我个人理解,
是属于分治的。
对本题来说,
你把整个线段分成若干小段,
再分下去,直到分成点树为止。
然后,利用递归求最小值,
改变值的时候也使用递归即可。
由于树的结构原因,
时间复杂度降为nlogn的,需要的空间稍大些。
program ty_1039;
var
i,n,m,k,ans,tot,bb,ww,cc,x,y:longint;
tree:array[0..200100]of
record
a,b,le,ri,da:longint;
end;
w,e:array[1..100000]of longint;
function min(x,y:longint):Longint;
begin
if x<y then exit(x);
exit(y);
end;
procedure maketree(l,r:longint);
var
now,mid:longint;
begin
tot:=tot+1;
now:=tot;
tree[now].a:=l;
tree[now].b:=r;
if l=r then begin tree[now].da:=w[l];exit;end;
mid:=(l+r)>>1;
tree[now].le:=tot+1;
maketree(l,mid);
tree[now].ri:=tot+1;
maketree(mid+1,r);
tree[now].da:=min(tree[tree[now].le].da,tree[tree[now].ri].da);
end;
function find(loc,x,y:longint):longint;
var
mid,i,j:longint;
begin
if (tree[loc].a=x)and(tree[loc].b=y) then exit(tree[loc].da);
mid:=(tree[loc].a+tree[loc].b)>>1;
if y<=mid then exit(find(tree[loc].le,x,y))
else if x>mid then exit(find(tree[loc].ri,x,y))
else begin
i:=find(tree[loc].le,x,mid);
j:=find(tree[loc].ri,mid+1,y);
exit(min(i,j));
end;
end;
procedure change(loc,x,y:longint);
var
mid:longint;
begin
if (tree[loc].a=x)and(x=tree[loc].b) then begin tree[loc].da:=y;exit;end;
mid:=(tree[loc].a+tree[loc].b)>>1;
if x<=mid then change(tree[loc].le,x,y)
else if x>mid then change(tree[loc].ri,x,y);
tree[loc].da:=min(tree[tree[loc].le].da,tree[tree[loc].ri].da);
end;
begin
assign(input,'ty.in');
reset(input);
assign(output,'ty.out');
rewrite(output);
readln(m,n);
for i:=1 to m do read(w[i]);
maketree(1,m);
for i:=1 to n do
begin
readln(bb,ww,cc);
if bb=1 then write(find(1,ww,cc),' ')
else change(1,ww,cc);
end;
close(input);
close(output);
end.

浙公网安备 33010602011771号