zoukankan      html  css  js  c++  java
  • NOIP2016全国信息学分区联赛提高组第二试 蚯蚓

    【问题描述】

    本题中,我们将用符号 LcJ 表示对 c 向下取整,例如: L3.0J = L3.1J = L3.9J = 3。   蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。    蛐蛐国里现在共有 n 只蚯蚓( n 为正整数)。每只蚯蚓拥有长度,我们设第 i 只蚯蚓的长度为 ai ( i = 1, 2, . . . , n ),并保证所有的长度都是非负整数(即:可能存在长度为0的蚯蚓)。
    

    蛐蛐国王当然知道怎么做啦! 但是他想考考你……
    【输入格式】

    从文件 earthworm.in 中读入数据。
    第一行包含六个整数 n, m, q, u, v, t ,其中: n, m, q 的意义见【问题描述】; u, v, t 均 为正整数;你需要自己计算 p = u/v (保证 0 < u < v );t 是输出参数,其含义将会在【输出格式】中解释。    
    第二行包含 n 个非负整数,为 a1, a2, . . . , an ,即初始时 n 只蚯蚓的长度。    同一行中相邻的两个数之间,恰好用一个空格隔开。   保证 1 ≤ n ≤ 105 , 0 ≤ m ≤ 7 × 106 , 0 < u < v ≤ 109 , 0 ≤ q ≤ 200 , 1 ≤ t ≤ 71 , 0 ≤ ai ≤ 108 。      
    

    【输出格式】

     输出到文件 earthworm.out    第一行输出 个整数,按时间顺序,依次输出第 t秒,第 2t 秒,第 3t 秒,......被切 断蚯蚓(在被切断前)的长度。第二行输出个整数,输出 m 秒后蚯蚓的长度:需要按从大到小的顺序,依次输出排名第 t ,第 2t ,第 3t ,. . . . . . 的长度。    同一行中相邻的两个数之间,恰好用一个空格隔开。即使某一行没有任何数需要输出,你也应输出一个空行。    请阅读样例来更好地理解这个格式。
    

    题解

    我们构建3个单调队列,分别记为q[0],q[1],q[2]。其中q[0]记录初始时每条蚯蚓的长度,并将其按从大到小的顺序排列。q[1]记录每次切割后长的那一截的长度。q[2]记录每次切割后短的那一截的长度。对于蚯蚓增长的长度,我们可以运用标记的思想,因为每条蚯蚓所增长的长度都是一样的。
    显然,这样子构出来的3个队列都是单调递减的,于是每次切割,取3个队列队首最大的元素进行切割,假设它的大小为x,当前增长长度为l,每单位时间蚯蚓长度增长L。那么,这条蚯蚓的长度len=x+l,切割后长度记为l1和l2,那么放入队列时将l1和l2都减去L+l,这样它们就可以和整个队列中的元素的标记同步了。
    需要输出的时候判断一下当前的时间是否是t的倍数即可。
    

    代码

    type
      arr=array [1..3] of longint;
    var
      gg:boolean;
      n,m,q,u,v,tn:longint;
      l,r:arr;
      a:array [1..3,0..10000001] of int64;
    procedure qsort(l,r:longint);
    var
      i,j:longint;
      mid,t:int64;
    begin
      if l>r then exit;
      i:=l; j:=r;
      mid:=a[1,(i+j) div 2];
      repeat
        while a[1,i]>mid do inc(i);
        while a[1,j]<mid do dec(j);
        if i<=j then
          begin
            t:=a[1,i]; a[1,i]:=a[1,j]; a[1,j]:=t;
            t:=a[2,i]; a[2,i]:=a[2,j]; a[2,j]:=t;
            t:=a[3,i]; a[3,i]:=a[3,j]; a[3,j]:=t;
            inc(i); dec(j);
          end;
      until i>j;
      qsort(l,j);
      qsort(i,r);
    end;
    
    procedure init;
    var
      i:longint;
    begin
      readln(n,m,q,u,v,tn);
      for i:=1 to n+m do
        begin
          a[1,i]:=-maxlongint;
          a[2,i]:=-maxlongint;
          a[3,i]:=-maxlongint;
        end;
      for i:=1 to n do
        read(a[1,i]);
      qsort(1,n); gg:=false;
    end;
    
    procedure main;
    var
      i,j,k:longint;
      max,x,y,tk,t:int64;
    begin
      l[1]:=1; r[1]:=n;
      l[2]:=1; r[2]:=0;
      l[3]:=1; r[3]:=0;
      for i:=1 to m do
        begin
          max:=-maxlongint;
          for j:=1 to 3 do
            if a[j,l[j]]>max then
              begin
                max:=a[j,l[j]];
                k:=j;
              end;
          t:=max+(i-1)*q;
          inc(l[k]);
          if i mod tn=0 then
            begin
              write(t,' ');
            end;
          x:=trunc(t*u/v); y:=trunc(t-x);
          if x<y then
            begin
              tk:=x; x:=y; y:=tk;
            end;
          inc(r[2]); a[2,r[2]]:=x-i*q;
          inc(r[3]); a[3,r[3]]:=y-i*q;
        end;
      writeln;
    end;
    
    procedure print;
    var
      i,j,k:longint;
      max,t:int64;
    begin
      for i:=1 to n+m do
        begin
          max:=-maxlongint;
          for j:=1 to 3 do
            if a[j,l[j]]>max then
              begin
                max:=a[j,l[j]];
                k:=j;
              end;
          t:=max+m*q;
          inc(l[k]);
          if i mod tn=0 then write(t,' ');
        end;
    end;
    
    begin
      init;
      main;
      print;
    end.
  • 相关阅读:
    51nod 1179 最大的最大公约数 (数论)
    POJ 3685 二分套二分
    POJ 3045 贪心
    LIC
    HDU 1029 Ignatius and the Princess IV
    HDU 1024 Max Sum Plus Plus
    HDU 2389 Rain on your Parade
    HDU 2819 Swap
    HDU 1281 棋盘游戏
    HDU 1083 Courses
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319536.html
Copyright © 2011-2022 走看看