Tyvj 1039 忠诚2

来源:互联网 发布:linux管理系统何明课件 编辑:程序博客网 时间:2024/04/30 16:58

题目:

 忠诚2

来源:

 Tyvj 1039

题目大意:

 给出N个数,M次操作,p=1时输出(a,b)中的最小值,p=2时把第x个数改成y

数据范围:

 m<=100000,n<=100000

样例:

 10 3

 1 2 3 4 5 6 7 8 9 10

 1 2 7

 2 2 0

 1 1 10

2 0

做题思路:

 曾经痴迷的线段树,动态起来和st比我认为还是线段树好理解

知识点:

 RMQ,线段树

const MaxN=100010; type tre=record l,r,lc,rc,min:longint;{<左右边界、左右儿子、区间最小值>} end;//trevar tree:array[0..MaxN*4] of tre; n,m,i,j,x,a,b,root,tot,ans,p:longint;procedure build(vart:longint;l,r:longint);{<建树>}begin inc(tot);t:=tot; tree[t].l:=l;tree[t].r:=r; tree[t].min:=maxlongint; ifl<r then begin  build(tree[t].lc,l,(l+r)div 2);  build(tree[t].rc,(l+r)div 2+1,r); end;//ifend;function min(a,b:longint):longint;begin ifa>b then exit(b); exit(a);end;procedure insert(t,i:longint);{<插入>}begin ift=0 then exit; iftree[t].l=tree[t].r then begin  tree[t].min:=x;  exit; end; iftree[tree[t].lc].r>=i then insert(tree[t].lc,i) else insert(tree[t].rc,i); tree[t].min:=min(tree[tree[t].lc].min,tree[tree[t].rc].min);{<维护区间最小值>}end;procedure find(t,l,r:longint);{<查找>}begin ift=0 then exit; if(tree[t].l=l)and(tree[t].r=r) then begin   ifans>tree[t].min then ans:=tree[t].min;{<由于该区间可能跨越子树所以做下比较>}  exit; end; iftree[tree[t].lc].r>=r then find(tree[t].lc,l,r) else   iftree[tree[t].rc].l<=l then find(tree[t].rc,l,r)    else    begin     find(tree[t].lc,l,tree[tree[t].lc].r);     find(tree[t].rc,tree[tree[t].rc].l,r);    end;end;begin readln(m,n); root:=0;tot:=0;  build(root,1,m); fori:=1 to m do begin  read(x);  insert(root,i); end; fori:=1 to n do begin  readln(p,a,x);   ifp=1 then   begin    ans:=maxlongint;{<初始化maxlongint才能更新>}    find(root,a,x);    write(ans,' ');   end  else   begin    insert(root,a);{<改变第x个数为y也就是把y插入到x位置上,然后更新所涉及的子树>}   end; end;end.
题目来源:http://www.tyvj.cn:8080/Problem_Show.asp?id=1039

原创粉丝点击