zoukankan      html  css  js  c++  java
  • BZOJ4721: [Noip2016]蚯蚓

    Description

    本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3。蛐蛐国最近蚯蚓成灾了!隔壁跳
    蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。蛐蛐国里现在共有n只蚯蚓(n为正整
    数)。每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可
    能存在长度为0的蚯蚓)。每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任选一个)
    将其切成两半。神刀手切开蚯蚓的位置由常数p(是满足0<p<1的有理数)决定,设这只蚯蚓长度为x,神刀手会将其
    切成两只长度分别为[px]和x-[px]的蚯蚓。特殊地,如果这两个数的其中一个等于0,则这个长度为0的蚯蚓也会被
    保留。此外,除了刚刚产生的两只新蚯蚓,其余蚯蚓的长度都会增加q(是一个非负整常数)。蛐蛐国王知道这样不
    是长久之计,因为蚯蚓不仅会越来越多,还会越来越长。蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是
    救兵还需要m秒才能到来......(m为非负整数)蛐蛐国王希望知道这m秒内的战况。具体来说,他希望知道:?m秒内
    ,每一秒被切断的蚯蚓被切断前的长度(有m个数)?m秒后,所有蚯蚓的长度(有n+m个数)。蛐蛐国王当然知道怎
    么做啦!但是他想考考你......

    Input

    第一行包含六个整数n,m,q,u,v,t,其中:n,m,q的意义见问题描述;
    u,v,t均为正整数;你需要自己计算p=u/v(保证0<u<v)t是输出参数,其含义将会在输出格式中解释。
    第二行包含n个非负整数,为ai,a2,...,an,即初始时n只蚯蚓的长度。
    同一行中相邻的两个数之间,恰好用一个空格隔开。
    保证1<=n<=10^5,0<m<7*10^6,0<u<v<10^9,0<=q<=200,1<t<71,0<ai<10^8。

    Output

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

    Sample Input

    3 7 1 1 3 1
    3 3 2

    Sample Output

    3 4 4 4 5 5 6
    6 6 6 5 5 4 4 3 2 2
    一开始模拟了个堆的做法结果被艹爆
    得换个东西,又和堆很像的,单调队列
    那就要弄出个单调性来,觉得不是很好想:
    开三个单调队列,分别存原来的,砍掉的,砍掉另外一半的
    那么先砍的一定比后砍的长,然后瞎做
    每次增加的定值q在砍的时候减掉最后再加上所有的
    下限开小AC感人
    //MT_LI
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int list[3][9110000];
    int head[3],tail[3];
    int n,m,q,u,v,t;
    int a[1110000];
    int main()
    {
        for(int i=0;i<=2;i++)head[i]=1,tail[i]=0;
        scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i=n;i>=1;i--)list[0][++tail[0]]=a[i];
        for(int ti=1;ti<=m;ti++)
        {
            int pos,maxx=-0x7fffffff;
            for(int i=0;i<=2;i++)if(list[i][head[i]]>maxx&&head[i]<=tail[i])maxx=list[i][head[i]],pos=i;
            head[pos]++;
            maxx+=(ti-1)*q;
            if(ti%t==0)
            {
                if(ti!=t)printf(" ");
                printf("%d",maxx);
            }
            list[1][++tail[1]]=(int)((ll)maxx*u/v)-q*ti;
            list[2][++tail[2]]=maxx-(int)((ll)maxx*u/v)-q*ti;
        }
        printf("
    ");
        for(int ti=1;ti<=n+m;ti++)
        {
            int maxx=-0x7fffffff,pos;
            for(int i=0;i<=2;i++)if(list[i][head[i]]>maxx&&head[i]<=tail[i])maxx=list[i][head[i]],pos=i;
            head[pos]++;
            if(ti%t==0)
            {
                if(ti!=t)printf(" ");
                printf("%d",maxx+m*q);
            }
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    bzoj 1030 [JSOI2007]文本生成器
    Swift 学习笔记 (闭包)
    Swift 学习笔记 (函数)
    HTML 学习笔记 JQueryUI(Interactions,Widgets)
    HTML 学习笔记 JQuery(表单,表格 操作)
    HTML 学习笔记 JQuery(animation)
    HTML 学习笔记 JQuery(盒子操作)
    HTML 学习笔记 JQuery(事件)
    HTML 学习笔记 JQuery(DOM 操作3)
    HTML 学习笔记 JQuery(DOM 操作2)
  • 原文地址:https://www.cnblogs.com/MT-LI/p/9879690.html
Copyright © 2011-2022 走看看