zoukankan      html  css  js  c++  java
  • 【noip2017 day2T2】【蚯蚓】巧用队列单调性线性处理

    这里写图片描述
    (画师当然是武内崇啦)

    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

    这道题我把题读错了,wa了好久

    当年我还什么都不会,强行每砍一次就排一次序。得了多少分我现在也无从得知了

    后来学了堆,有一道题叫“合并果子”,其实和这道题很像。
    相信大家都做过合并果子,这道题有两种方法:
    1、堆
    2、队列
    当时Mr.hu说合并果子就是堆的裸题。然而队列的复杂度是o(n)的,其实更优。此题同理。若用堆做,只能过60分。

    我们开3个队列,大的那部分扔进一个队列,小的那部分扔进一个队列。可以证明这个队列是单调的。
    对于这个时间的问题,可以对每只蚯蚓附加一个时间信息,表示它的诞生时间。当要取的时候,把当前时间减去诞生时间,就可以计算其长度了。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long 
    using namespace std;
    
    ll n,m,qq,u,v,k;
    ll a[1000005];
    double p;
    queue<pair<ll,ll> > q[3];
    
    bool cmp(const ll &x,const ll &y){
        return x>y;
    }
    int main(){
        memset(a,0,sizeof(a));
        cin>>n>>m>>qq>>u>>v>>k;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++) q[0].push(make_pair(a[i],0));
        ll fq,cut,t;
        for(int i=1;i<=m;i++){
            cut=0;
            for(int j=0;j<3;j++){
                if(q[j].empty()) continue;
                t=i-q[j].front().second-1;
                if(q[j].front().first+t*qq>cut){
                    cut=q[j].front().first+t*qq;
                    fq=j;
                }
            }
            if(i%k==0) cout<<cut<<" ";
            q[1].push(make_pair(cut*u/v,i));
            q[2].push(make_pair(cut-cut*u/v,i));
            q[fq].pop();
        }
        printf("
    ");
        ll cnt=0;
        while(!(q[0].empty()&&q[1].empty()&&q[2].empty())){
            cnt++;
            cut=0;
            for(int j=0;j<3;j++){
                if(q[j].empty()) continue;
                t=m-q[j].front().second;
                if(q[j].front().first+t*qq>cut){
                    cut=q[j].front().first+t*qq;
                    fq=j;
                }
            }
            q[fq].pop();
            if(cnt%k==0){
                cout<<cut<<" ";
            }
        }
        return 0;
    }
  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/LinnBlanc/p/7763122.html
Copyright © 2011-2022 走看看