• poj1823,3667


    又来练线段树了……

    poj1823题意很简单(明显的数据结构题),区间修改和统计最长连续空区间;

    有了poj3468的基础,区间修改不是什么问题了,重点是求最长连续空区间;(弱弱的我纠结了好久)

    在每个节点上增加3个域,lmax,rmax,maxx,分别表示从左起最长,右起最长,区间内最长,然后稍稍动点脑筋即可……

     1 type node=record
     2        lmax,rmax,maxx:longint;
     3        l,r,lazy:integer;   //lazy表示区间三种情况,-1表示区间内有人住但未满,0表示无人住,1表示全住满
     4      end;
     5 var tree:array[0..80000] of node;
     6     i,n,m,a,b,c,j:longint;
     7 procedure updata(i:longint);     //更新
     8   var p:longint;
     9   begin
    10     if tree[i].lazy<>-1 then
    11     begin
    12       if tree[i].lazy=0 then p:=tree[i].r-tree[i].l+1 else p:=0;
    13       tree[i].lmax:=p;
    14       tree[i].rmax:=p;
    15       tree[i].maxx:=p;
    16     end
    17     else begin        //看起来很繁琐,实际上仔细想想就明白了
    18       tree[i].lmax:=tree[i*2].lmax;
    19       if tree[i].lmax=tree[i*2].r-tree[i*2].l+1 then tree[i].lmax:=tree[i].lmax+tree[i*2+1].lmax;
    20       tree[i].rmax:=tree[i*2+1].rmax;
    21       if tree[i].rmax=tree[i*2+1].r-tree[i*2+1].l+1 then tree[i].rmax:=tree[i].rmax+tree[i*2].rmax;
    22       p:=max(tree[i].lmax,tree[i].rmax);
    23       p:=max(p,max(tree[i*2].maxx,tree[i*2+1].maxx));
    24       tree[i].maxx:=max(p,tree[i*2].rmax+tree[i*2+1].lmax);
    25     end;
    26   end;
    27 
    28 procedure pushdown(i:longint);  //lazy思想,注意标记下移的时候不忘更新,因为某个子区间不一定会被访问
    29   begin
    30     tree[i*2].lazy:=tree[i].lazy;
    31     updata(i*2);
    32     tree[i*2+1].lazy:=tree[i].lazy;
    33     updata(i*2+1);
    34     tree[i].lazy:=-1;    //需要标记下移的时候当前区间一定不会是全满或全空(想想为什么)
    35   end;
    36 
    37 procedure build(i,l,r:longint);  //初始化线段树
    38   var m:longint;
    39   begin
    40     tree[i].l:=l; tree[i].r:=r;
    41     tree[i].lazy:=0;
    42     updata(i);
    43     if l<>r then
    44     begin
    45       m:=(l+r) div 2;
    46       build(i*2,l,m);
    47       build(i*2+1,m+1,r);
    48     end;
    49   end;
    50 
    51 procedure work(i,l,r,t:longint);
    52   var m:longint;
    53   begin
    54     if (l>=a) and (r<=b) then
    55     begin
    56       tree[i].lazy:=t;
    57       updata(i);
    58     end
    59     else if l<>r then begin
    60       if tree[i].lazy<>-1 then pushdown(i); 
    61       m:=(l+r) div 2;
    62       if (a<=m) then work(i*2,l,m,t);
    63       if (b>=m+1) then work(i*2+1,m+1,r,t);
    64       updata(i);   // 左右子区间访问过后更新当前区间
    65     end;
    66   end;
    67 begin
    68   readln(n,m);
    69   build(1,1,n);
    70   for i:=1 to m do
    71   begin
    72     read(c);
    73     if c<>3 then
    74     begin
    75       readln(a,b);
    76       b:=a+b-1;
    77       if c=1 then work(1,1,n,1) else work(1,1,n,0);  //1代表入住,0代表退房
    78     end
    79     else if c=3 then writeln(tree[1].maxx);
    80   end;
    81 end.
    poj1823

    话说线段树查起来真累(难道还是我太渣了?),耗了5次才AC

    poj3667在poj1823基础上多了个查找但并不难,对于当前区间,按照从左区间到右区间的优先顺序找即可,一次AC

      1 type node=record
      2        l,r,lmax,rmax,maxx:longint;
      3        lazy:integer;
      4      end;
      5 
      6 var tree:array[0..200000] of node;
      7     i,n,m,a,b,c,j,l:longint;
      8 function max(a,b:longint):longint;
      9   begin
     10     if a>b then max:=a else max:=b;
     11   end;
     12 
     13  function min(a,b:longint):longint;
     14    begin
     15      if a=0 then exit(b);
     16      if b=0 then exit(a);
     17      if a>b then exit(b) else exit(a);
     18    end;
     19 procedure updata(i:longint);
     20   var p:longint;
     21   begin
     22     if tree[i].lazy<>-1 then
     23     begin
     24       if tree[i].lazy=0 then p:=tree[i].r-tree[i].l+1 else p:=0;
     25       tree[i].lmax:=p;
     26       tree[i].rmax:=p;
     27       tree[i].maxx:=p;
     28     end
     29     else begin
     30       tree[i].lmax:=tree[i*2].lmax;
     31       if tree[i].lmax=tree[i*2].r-tree[i*2].l+1 then tree[i].lmax:=tree[i].lmax+tree[i*2+1].lmax;
     32       tree[i].rmax:=tree[i*2+1].rmax;
     33       if tree[i].rmax=tree[i*2+1].r-tree[i*2+1].l+1 then tree[i].rmax:=tree[i].rmax+tree[i*2].rmax;
     34       p:=max(tree[i].lmax,tree[i].rmax);
     35       p:=max(p,max(tree[i*2].maxx,tree[i*2+1].maxx));
     36       tree[i].maxx:=max(p,tree[i*2].rmax+tree[i*2+1].lmax);
     37     end;
     38   end;
     39 
     40 procedure pushdown(i:longint);
     41   begin
     42     tree[i*2].lazy:=tree[i].lazy;
     43     updata(i*2);
     44     tree[i*2+1].lazy:=tree[i].lazy;
     45     updata(i*2+1);
     46     tree[i].lazy:=-1;
     47   end;
     48 
     49 procedure find(i:longint);
     50   begin
     51     if tree[i].maxx<l then exit;
     52     if (tree[i].lmax>=l) then a:=tree[i].l
     53     else if tree[2*i].maxx>=l then
     54       find(2*i)
     55     else if tree[i*2].rmax+tree[i*2+1].lmax>=l  then
     56     begin
     57       a:=tree[i*2].r-tree[i*2].rmax+1;
     58     end
     59     else if tree[i*2+1].maxx>=l then find(2*i+1);
     60     if tree[i].rmax>=l then a:=min(a,tree[i].r-tree[i].rmax+1);
     61   end;
     62 
     63 procedure build(i,l,r:longint);
     64   var m:longint;
     65   begin
     66     tree[i].l:=l; tree[i].r:=r;
     67     tree[i].lazy:=0;
     68     updata(i);
     69     if l<>r then
     70     begin
     71       m:=(l+r) div 2;
     72       build(i*2,l,m);
     73       build(i*2+1,m+1,r);
     74     end;
     75   end;
     76 
     77 procedure work(i,l,r,t:longint);
     78   var m:longint;
     79   begin
     80     if (l>=a) and (r<=b) then
     81     begin
     82       tree[i].lazy:=t;
     83       updata(i);
     84     end
     85     else if l<>r then begin
     86       if tree[i].lazy<>-1 then pushdown(i);
     87       m:=(l+r) div 2;
     88       if (a<=m) then work(i*2,l,m,t);
     89       if (b>=m+1) then work(i*2+1,m+1,r,t);
     90       updata(i);
     91     end;
     92   end;
     93 
     94 begin
     95   readln(n,m);
     96   build(1,1,n);
     97   for i:=1 to m do
     98   begin
     99     read(c);
    100     if c=1 then
    101     begin
    102       readln(l);
    103       a:=0;
    104       find(1);
    105       writeln(a);
    106       b:=a+l-1;
    107       if a<>0 then work(1,1,n,1);
    108     end
    109     else if c=2 then
    110     begin
    111       readln(a,b);
    112       b:=a+b-1;
    113       work(1,1,n,0);
    114     end;
    115   end;
    116 end.
    poj3667
  • 相关阅读:
    js实现考试倒计时
    freemarker常见语法大全
    页面修改图片路径
    freemaker页面字符串特殊字符显示异常处理
    win10家庭版远程连接 要求的函数不受支持
    mysql出现提示错误10061的解决方法
    freemark
    面对众多的前端框架,你该如何学习?
    HBase 入门
    Hive 优化
  • 原文地址:https://www.cnblogs.com/phile/p/4473303.html
Copyright © 2020-2023  润新知