zoukankan      html  css  js  c++  java
  • CodeVS 1299-切水果

    原题

    题目描述 Description

    简单的说,一共N个水果排成一排,切M次,每次切[L,R]区间的所有水果(可能有的水果被重复切),每切完一次输出剩下水果数量.

    数据已重新装配,不会出现OLE错误.

    时限和数据范围适当修改,避免数据包过大而浪费空间资源.

    输入描述 Input Description

    第1行共包括2个正整数,分别为N,M.

    接下来m行每行两个正整数L,R.

    输出描述 Output Description

    一共输出M行,每行输出切完之后剩下水果数量.

    样例输入 Sample Input

    10 3

    3 5

    2 8

    1 5

    样例输出 Sample Output

    7

    3

    2

    数据范围及提示 Data Size & Hint

    30%的数据满足N,M<=5,000

    60%的数据满足N,M<=100,000

    100% 的数据满足1<=L<=R<=N<=500,000,1<=M<=500,000

    题解

    很明显的线段树,但我80分tle了很多次,没想到啊25行的线段树还会tle,后来加了个判断机制就AC了.

    这道题其实有一个奇技淫巧,就是让整个线段树的初值全部设为0,然后再一个个区间读入,将区间统一赋值成1,最后ans=N-sum[1].

    最最关键的,是将set过的区间标记起来,如果标记过,那么就直接跳过,不然就tle了2333.

    下面是代码:

    var sum,st:array[1..2000000] of int64;
    var en:array[1..2000000] of boolean;
    var n,m,x,y:int64;
    var i:longint;
    procedure sett(h,l,r,x,y,num:longint);
    var m,p:longint;
    begin
      p:=0;
      if (l>=x)and(r<=y) then begin st[h]:=num;en[h]:=true;exit; end;//标记区间
      m:=(l+r)>>1;
      if (x<=m)and(not en[h<<1]) then sett(h<<1,l,m,x,y,num);//处理左边区间
      if (y>m)and(not en[h<<1+1]) then sett(h<<1+1,m+1,r,x,y,num);//处理右边区间
      if en[h<<1] then p:=(m-l+1)*st[h<<1] else p:=sum[h<<1];
      if en[h<<1+1] then inc(p,(r-m)*st[h<<1+1]) else inc(p,sum[h<<1+1]);
      sum[h]:=p;//每次更新父亲节点的sum值
    end;
    begin
      readln(n,m);
      for i:=1 to m do
      begin
        readln(x,y);
        sett(1,1,n,x,y,1);
        writeln(n-sum[1]);//奇技淫巧
      end;
    end.

    欢迎转载,若转载请注明出处.

  • 相关阅读:
    amd
    富文本编辑器
    css module
    uc浏览器调试
    mysql利用sql语句将查询结果导出
    自启程序为何自启失败?
    nginx4层代理ssh服务
    创建SFTP用户并指定访问目录 Linux
    01月04日17:15:40 学习进度笔记
    01月04日10:39:23总结
  • 原文地址:https://www.cnblogs.com/HAdolf-HQY/p/6501535.html
Copyright © 2011-2022 走看看