zoukankan      html  css  js  c++  java
  • 【NOIP2016】蚯蚓

    Description

    本题中,我们将用符号 ⌊c⌋表示对 cc 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋=3。

    蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。

    蛐蛐国里现在共有 n 只蚯蚓(n 为正整数)。每只蚯蚓拥有长度,我们设第 i 只蚯蚓的长度为 ai (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

    Pic

    Output

    Pic

    Sample Input

    样例1输入: 
    3 7 1 1 3 1 
    3 3 2

    样例2输入: 
    3 7 1 1 3 2 
    3 3 2

    样例3输入: 
    3 7 1 1 3 9 
    3 3 2

    Sample Output

    样例1输出: 
    3 4 4 4 5 5 6 
    6 6 6 5 5 4 4 3 2 2

    样例2输出: 
    4 4 5 
    6 5 4 3 2

    样例3输出:

    2

    Hint

    样例1提示: 
    在神刀手到来前:3只蚯蚓的长度为3,3,2。 
    1秒后:一只长度为3的蚯蚓被切成了两只长度分别为1和2的蚯蚓,其余蚯蚓的长度增加了1。最终4只蚯蚓的长度分别为((1,2),4,3。括号表示这个位置刚刚有一只蚯蚓被切断。 
    2秒后:一只长度为4的蚯蚓被切成了1和3 0 5只蚯蚓的长度分别为:2,3,(1,3),4。 
    3秒后:一只长度为4的蚯蚓被切断。6只蚯蚓的长度分别为:3,4,2,4,(1,3)。 
    4秒后:一只长度为4的蚯蚓被切断。7只蚯蚓的长度分别为:4,(1,3),3,5,2,4。 
    5秒后:一只长度为5的蛆叫被切断。8只蚯蚓的长度分别为:5,2,4,4,(1,4),3,5。 
    6秒后:一只长度为5的蚯蚓被切断。9只蚯蚓的长度分别为:(1,4),3,5,5,2,5,4,6。 
    7秒后:一只长度为6的蚯蚓被切断。10只蚯蚓的长度分别为:2,5,4,6,6,3,6,5,(2,4)。 
    所以,7秒内被切断的蚯蚓的长度依次为3,4,4,4,5,5,60 7秒后,所有蚯蚓长度从大到小排序为6,6,6,5,5,4,4,3,2,2。

    样例2提示: 
    这个数据中只有t=2与上个数据不同。只需在每行都改为每两个数输出一个数即可 虽然第一行最后有一个6没有被输出,但是第二行仍然要重新从第二个数再开始输出

    样例3提示: 
    这个数据中只有t=9与上个数据不同。 注意第一行没有数要输出,但也要输出一个空行。

    数据约束:

    P

     
     
    题解:
      首先,对于75分做法,我们可以先写一个堆,当然每天的增加量不是特别好维护,所以我们用堆维护一个相对值,定义tag为增加量,然后所有的值都是以他为标准的,所以每次加入堆的时候都先要拿算出来的值-tag,然后把相对值向里面丢,相应的,取出来的元素也要把tag加回,这样的话,就可以水过75分。
      知道这个100分就十分好想了,开3个队列,第一个存最初的蚯蚓(那么我们sort一下),其余的两个队列分别存砍断的那两个蚯蚓,因为我们每次都是那最大的出来砍断,那么最大的*一个常数一定比小的乘以常数要大,所以这3个队列是满足单调的,那么我们每次只有比较3个队列的队首就可以了。
      增加问题一样用tag解决,注意,这个题目必须要手写队列!以上。
     
    代码:75分(堆)
    #include<queue>
    #include<algorithm>
    #include<stdio.h>
    #include<iostream>
    #define ll long long
    const int inf=(1<<30);
    const int MAXN=100050;
    using namespace std;
    struct qiu{
        int len;
        bool operator < (const qiu&x)const {
            return x.len>len;
        }
        qiu(){}
        qiu(int _len):len(_len){}
    };
    priority_queue<qiu> q;
    vector<int> ans;
    vector<int> a;
    int n,m,add,t;
    ll tag=0;
    double u,v;
    int main(){
        cin>>n>>m>>add>>u>>v>>t;
        while(!q.empty()) q.pop();
        while(!a.empty()) a.pop_back();
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            q.push(qiu(x));
        }
        for(int day=1;day<=m;day++){
            int maxx=q.top().len+tag;q.pop();
            int h=(maxx*u)/v;
            int hh=maxx-h;
            tag+=add;
            q.push(qiu(h-tag));
            q.push(qiu(hh-tag));
            ans.push_back(maxx);
        }
        for(int i=t-1;i<m;i+=t) printf("%d ",ans[i]);
        printf("
    ");
        while(!q.empty()){
            qiu x=q.top();q.pop();
            a.push_back(x.len+tag);
        }
        int lenn=a.size();
        for(int i=t-1;i<lenn;i+=t) printf("%d ",a[i]); 
    }

    AC代码:

    #include<queue>
    #include<algorithm>
    #include<stdio.h>
    #include<iostream>
    #define ll long long
    #define inf -99999999999
    const int MAXN=7000011;
    using namespace std;
    int q[3][MAXN],head[3],tail[3];
    int anss[MAXN*3],a[MAXN*3],numm[3];
    int n,m,add,t,tag=0,num=0;
    double u,v;
     
    bool cmp(int x,int y){return x>y;}
     
    int main(){
        cin>>n>>m>>add>>u>>v>>t;
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            q[0][++tail[0]]=x;
        }
        sort(q[0]+1,q[0]+tail[0]+1,cmp);
        tail[1]=tail[2]=0;
        head[0]=head[1]=head[2]=1;
        for(int day=1;day<=m;day++){
            int maxx=inf,from=-1;
            for(int i=0;i<3;i++){
                if(head[i]<=tail[i]){
                    if(maxx<q[i][head[i]]) maxx=q[i][head[i]],from=i;
                }
            }
            maxx+=tag;
            int h=(maxx*u)/v;
            int hh=maxx-h;
            tag+=add;
            q[1][++tail[1]]=h-tag;
            q[2][++tail[2]]=hh-tag;
            head[from]++;
            anss[numm[1]++]=maxx;
        }
        for(int i=t-1;i<m;i+=t) printf("%d ",anss[i]);
        printf("
    ");
        int hh=t,day=1;
        while(1){
        int FF=0,from=0,maxn=inf;
        if(head[0]<=tail[0])
          if(q[0][head[0]]>maxn)
                    maxn=q[0][head[0]],FF=1,from=0;
        if(head[1]<=tail[1])
          if(q[1][head[1]]>maxn)
                    maxn=q[1][head[1]],FF=1,from=1;
        if(head[2]<=tail[2])
                if(q[2][head[2]]>maxn)
                    maxn=q[2][head[2]],FF=1,from=2;
        if(FF==0) break;
        if(from==0) ++head[0];
        else if(from==1) ++head[1];
        else ++head[2];
        if(hh==day)  printf("%d ",maxn+tag),hh+=t;
        ++day;
      }
    }
  • 相关阅读:
    桟错误分析方法
    gstreamer调试命令
    sqlite的事务和锁,很透彻的讲解 【转】
    严重: Exception starting filter struts2 java.lang.NullPointerException (转载)
    eclipse 快捷键
    POJ 1099 Square Ice
    HDU 1013 Digital Roots
    HDU 1087 Super Jumping! Jumping! Jumping!(动态规划)
    HDU 1159 Common Subsequence
    HDU 1069 Monkey and Banana(动态规划)
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7368056.html
Copyright © 2011-2022 走看看