zoukankan      html  css  js  c++  java
  • [vijos P1448] 校门外的树

    忘了这是第几道“校门外的树”的,翻了下tyvj发现叫这名字的有三道题- -。括号法真是好东西。

    一开始搜题目归类想练线段树的,结果看解题发现这题树状数组更好做,其实也是树状数组更容易理解。今天早上物理课就在比划这道题。

    写BIT算法的时候犯的错就是忘记给function里的ans清零的- -一开始我看output都差1我还以为是算法错了。

    program vijos_p1448;
    var i,j,m,n,k,a,b,tot,t1,t2,ans:longint;
        f:array[1..200000,1..2] of integer;
    function lowbit(x:longint):longint;
    begin
      lowbit:=x and (-x);
    end;
    
    procedure add(x,node:longint);
    begin
      while x<=n do
        begin
          inc(f[x,node]);
          x:=x+lowbit(x);
        end;
    end;
    
    function getsum(x,node:longint):longint;
    var ans:longint;
    begin
      ans:=0;
      while x>0 do
        begin
          ans:=ans+f[x,node];
          x:=x-lowbit(x);
        end;
      exit(ans);
    end;
    
    begin
      readln(n,m);
      for i:=1 to m do
        begin
          readln(k,a,b);
          if k=1 then
            begin
              inc(tot);
              add(a,1);
              add(b,2);
            end;
          if k=2 then
            begin
              t1:=getsum(a-1,2);
              t2:=tot-getsum(b,1);
              ans:=tot-t1-t2;
              writeln(ans);
            end;
        end;
    end.
    校门外的树-BIT

    测试数据 #0: Accepted, time = 0 ms, mem = 1516 KiB, score = 1

    测试数据 #1: Accepted, time = 0 ms, mem = 1516 KiB, score = 1

    测试数据 #2: Accepted, time = 29 ms, mem = 1516 KiB, score = 1

    测试数据 #3: Accepted, time = 31 ms, mem = 1512 KiB, score = 1

    测试数据 #4: Accepted, time = 41 ms, mem = 1516 KiB, score = 1

    测试数据 #5: Accepted, time = 100 ms, mem = 1516 KiB, score = 1

    测试数据 #6: Accepted, time = 40 ms, mem = 1512 KiB, score = 1

    测试数据 #7: Accepted, time = 46 ms, mem = 1516 KiB, score = 1

    测试数据 #8: Accepted, time = 62 ms, mem = 1516 KiB, score = 1

    测试数据 #9: Accepted, time = 117 ms, mem = 1516 KiB, score = 1

    Accepted, time = 466 ms, mem = 1516 KiB, score = 10

    后来开始码线段树了,难于理解的是这题要改的是点,而不是段,我的做法是自动吧点x扩充成x~x+1的线段。这写得麻烦的竟然有6个参数肯定有更简单的代码嗯哼=。=而且我也不确定这算不算线段树了总感觉怪怪的,时间效率上貌似稍微差一点,不过差别这么细微忽略好了。

    这里犯了个错误就是既然扩充点成线段,那么边界就该是n+1。k=2时getsum中a和b的边界也要改。

    咳咳一不小心数组开大了,因为一开始边界问题以为是数组没开大问题…

    program vijos_p1448_3;
    var f:array[1..200000,1..2] of longint;
        k,a,b,i,n,m,tot,t1,t2,ans:longint;
    procedure add(p,left,right,x,y,node:longint);
    var mid:longint;
    begin
      if (x=left) and (y=right) then
        begin
          inc(f[p,node]);
          exit;
        end;
      mid:=(left+right) div 2;
      if y<=mid then
        begin
          add(2*p,left,mid,x,y,node);
          f[p,node]:=f[p,node]+1;
        end
      else if x>=mid then
        begin
          add(2*p+1,mid,right,x,y,node);
          f[p,node]:=f[p,node]+1;
        end
      else begin
             add(2*p,left,mid,x,mid,node);
             add(2*p+1,mid,right,mid,y,node);
             f[p,node]:=f[p,node]+1;
           end;
    end;
    
    function getsum(p,left,right,x,y,node:longint):longint;
    var ans,mid:longint;
    begin
      if (x=left) and (y=right) then exit(f[p,node]);
      mid:=(left+right) div 2;
      if y<=mid then exit(getsum(2*p,left,mid,x,y,node))
      else if x>=mid then exit(getsum(2*p+1,mid,right,x,y,node))
      else exit(getsum(2*p,left,mid,x,mid,node)+getsum(2*p+1,mid,right,mid,y,node));
    end;
    
    begin
      readln(n,m);
      for i:=1 to m do
        begin
          readln(k,a,b);
          if k=1 then
            begin
              inc(tot);
              add(1,1,n+1,a,a+1,1);
              add(1,1,n+1,b,b+1,2);
            end;
          if k=2 then
            begin
              t1:=getsum(1,1,n+1,1,a,2);
              t2:=tot-getsum(1,1,n+1,1,b+1,1);
              ans:=tot-t1-t2;
              writeln(ans);
            end;
        end;
    end.
    校门外的树-ST

    测试数据 #0: Accepted, time = 0 ms, mem = 32048 KiB, score = 1

    测试数据 #1: Accepted, time = 0 ms, mem = 32052 KiB, score = 1

    测试数据 #2: Accepted, time = 31 ms, mem = 32048 KiB, score = 1

    测试数据 #3: Accepted, time = 46 ms, mem = 32048 KiB, score = 1

    测试数据 #4: Accepted, time = 62 ms, mem = 32048 KiB, score = 1

    测试数据 #5: Accepted, time = 54 ms, mem = 32048 KiB, score = 1

    测试数据 #6: Accepted, time = 54 ms, mem = 32048 KiB, score = 1

    测试数据 #7: Accepted, time = 78 ms, mem = 32048 KiB, score = 1

    测试数据 #8: Accepted, time = 83 ms, mem = 32048 KiB, score = 1

    测试数据 #9: Accepted, time = 124 ms, mem = 32048 KiB, score = 1

    Accepted, time = 532 ms, mem = 32052 KiB, score = 10

  • 相关阅读:
    Oracle DB 使用单行函数定制输出
    NDK编译多个cpp
    使用NDK编译的时候出现 undefined reference to
    linux SSSocket 简单封装
    OCP-1Z0-051-V9.02-70题
    OCP-1Z0-051-V9.02-69题
    OCP-1Z0-051-V9.02-68题
    OCP-1Z0-051-V9.02-67题
    OCP-1Z0-051-V9.02-66题
    OCP-1Z0-051-V9.02-65题
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3583656.html
Copyright © 2011-2022 走看看