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.