线段树

hdu3308

//线段树,求区间最长上升连续序列长度,有更新
program tt;
type point=record
      l,r,lmax,rmax,max:longint;
     end;
var tree:array[1..400000]of point;
    n,m,t1,a2,b,l,i:longint;
    a:array[0..100000]of longint;
    ch,ch1:char;
function max(a,b:longint):longint;
begin
 if a<b then max:=b else max:=a;
end;
function min(a,b:longint):longint;
begin
 if a<b then min:=a else min:=b;
end;
procedure build(p,l,r:longint);
var mid:longint;
begin
 tree[p].l:=l;
 tree[p].r:=r;
 if l=r then
  begin
   tree[p].max:=1;
   tree[p].lmax:=1;tree[p].rmax:=1;
  end
 else
  begin
   mid:=(l+r) div 2;
   build(p+p,l,mid);
   build(p+p+1,mid+1,r);
   tree[p].lmax:=tree[p+p].lmax;

   if (tree[p+p].lmax=mid-l+1)and(a[mid]<a[mid+1]) then inc(tree[p].lmax,tree[p+p+1].lmax);
   tree[p].rmax:=tree[p+p+1].rmax;
   if (tree[p+p+1].rmax=r-mid)and(a[mid]<a[mid+1]) then inc(tree[p].rmax,tree[p+p].rmax);
   tree[p].max:=max(tree[p+p].max,tree[p+p+1].max);
   if a[mid]<a[mid+1] then
    tree[p].max:=max(tree[p].max,tree[p+p].rmax+tree[p+p+1].lmax);
  end;
end;
procedure updata(p,a1,b:longint);
var t,mid:longint;
begin
 if (tree[p].l=tree[p].r) then
  begin
   a[a1]:=b;
   exit;
  end;
 mid:=(tree[p].l+tree[p].r) div 2;
 if a1<=mid then updata(p+p,a1,b);
 if a1>mid then updata(p+p+1,a1,b);

 tree[p].lmax:=tree[p+p].lmax;
 if (tree[p+p].lmax=mid-tree[p].l+1)and(a[mid]<a[mid+1]) then inc(tree[p].lmax,tree[p+p+1].lmax);
 tree[p].rmax:=tree[p+p+1].rmax;
 if (tree[p+p+1].rmax=tree[p].r-mid)and(a[mid]<a[mid+1]) then inc(tree[p].rmax,tree[p+p].rmax);

 t:=max(tree[p+p].max,tree[p+p+1].max);
 if a[mid]<a[mid+1] then
  t:=max(t,tree[p+p].rmax+tree[p+p+1].lmax);
 tree[p].max:=t;
end;




function find(p,l,r:longint):longint;
var t,mid:longint;
begin
 if (tree[p].l=l)and(tree[p].r=r) then begin find:=tree[p].max;exit;end;
 mid:=(tree[p].l+tree[p].r) div 2;
 if r<=mid then find:=find(p+p,l,r);
 if l>mid then find:=find(p+p+1,l,r);
 if (l<=mid)and(r>mid) then
  begin
   t:=max(find(p+p,l,mid),find(p+p+1,mid+1,r));
   if (a[mid]<a[mid+1]) then
    t:=max(t,min(tree[p+p].rmax,mid-l+1)+min(tree[p+p+1].lmax,r-mid));
   find:=t;
  end;
end;

begin
 read(t1);
 for l:=1 to t1 do
  begin
   read(n,m);
   for i:=0 to n-1 do read(a[i]);
   build(1,0,n-1);
   readln;
   for i:=1 to m do
    begin
     readln(ch,ch1,a2,b);
     if ch='U' then
      begin
       updata(1,a2,b);
      end
     else
      writeln(find(1,a2,b));
    end;
  end;
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值