poj 2823 Sliding Window(线段树)

题目

线段树的单点更新,没什么好讲的…

program poj_2823;
const maxN = 2500000;
type rec = record
     left,right,mark,value1,value2:longint; 
        //value1为最大值 value2为最小值
end;
var         
 n,k,i,a:longint;
 tree:array[1..maxN]of rec;
function max(a,b:longint):longint;
begin
 if a>b then max:=a
  else max:=b;
end;

function min(a,b:longint):longint;
begin
 if a<b then min:=a
 else min:=b;
end;

procedure buildtree(l,r,k:longint);
var
   mid:longint;
begin
 tree[k].left:=l;
 tree[k].right:=r;
 tree[k].value1:=0;
 tree[k].value2:=0;
 if (l=r) then exit;
 mid:=(l+r)div 2;
 buildtree(l,mid,k*2);
 if mid<r then buildtree(mid+1,r,k*2+1);
end;

procedure update(x,w,k:longint);
begin
 if (tree[k].left=x)and(tree[k].right=x) then begin
  tree[k].value1:=w;
  tree[k].value2:=w;
  exit;
 end;
 if (tree[k*2].right>=x) then update(x,w,k*2)
 else update(x,w,k*2+1);
 tree[k].value1:=max(tree[k*2].value1,tree[k*2+1].value1);
 tree[k].value2:=min(tree[k*2].value2,tree[k*2+1].value2);
end;

function query1(l,r,k:longint):longint;
                 //查找最大值
begin
 if (tree[k].left=l)and(tree[k].right=r) then begin
  query1:=tree[k].value1;
  exit;
 end;
 if tree[k*2].right>=r then query1:=query1(l,r,k*2)
 else if tree[k*2+1].left<=l then query1:=query1(l,r,k*2+1)
 else query1:=max(query1(l,tree[k*2].right,k*2),query1(tree[k*2+1].left,r,k*2+1));
end;

function query2(l,r,k:longint):longint;
               //查最小值
begin
 if (tree[k].left=l)and(tree[k].right=r) then begin
  query2:=tree[k].value2;
  exit;
 end;
 if tree[k*2].right>=r then query2:=query2(l,r,k*2)
 else if tree[k*2+1].left<=l then query2:=query2(l,r,k*2+1)
 else query2:=min(query2(l,tree[k*2].right,k*2),query2(tree[k*2+1].left,r,k*2+1));
end;

begin
 readln(n,k);
 buildtree(1,n,1);
 for i:=1 to n do begin
  read(a);
  update(i,a,1);
 end;
 for i:=1 to n-k+1 do
   write(query2(i,i+k-1,1),' ');
 writeln;
 for i:=1 to n-k+1 do
   write(query1(i,i+k-1,1),' ');
end.

Memory:41964K
Time:6860MS

1.感觉这样做好慢…
2.在网上搜到了单调队列的做法…不会,马上滚去看…
3.一直搞不懂数组开多大才好…好烦…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值