线段树的单点更新,没什么好讲的…
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.一直搞不懂数组开多大才好…好烦…