zoukankan      html  css  js  c++  java
  • [洛谷P2827]蚯蚓

     

    题目描述:https://www.luogu.org/problemnew/show/P2827

    解析:

     

    暴力做法:建立优先队列,每次要切的时候从队首弹出切完再插进去。考虑怎么处理q:被切的蚯蚓不能增长等同于相对于其他蚯蚓负增长了q,于是想到记录当前总增长的长度sum(即t*q)。每次从队首取出元素的时候加上sum,计算完答案后再减去加过q的sum。时间复杂度O(mlog2n).

    正解:发现长蚯蚓相较于短蚯蚓被切后仍然是更长的,具有单调性。于是想到另外开两个数组来记录被切蚯蚓的第一段与被切蚯蚓的第二段。每次要切的时候从取三个队首的最大值。切完之后分别加入第二个队列和第三个队列。

    细节:1.注意精度问题 2.注意数组开的大小,队首和队尾会不停的往后移 3.注意清空队列时要清成-0x3f3f3f,因为如果清成0,当队列为空时,队首元素为0,但其他队首元素可能为负

    附上代码:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<cstring>
    using namespace std;
    
    typedef long long LL;
    const int maxn=1e6+5;
    int n,m,q,u,v,t;
    LL q1[10*maxn],q2[10*maxn],q3[10*maxn];
    int h1,t1,h2,t2,h3,t3;
    LL sum=0;
    priority_queue<LL> ans;
    
    inline LL read() 
    {
        LL ret=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
        while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
        return ret*f;
    }
    
    inline LL max(LL a,LL b){
        return a>b?a:b;
    }
    
    inline bool cmp(const LL &a,const LL &b){
        return a>b;
    }
    
    inline LL getmax(){
        LL ans1,ans2,ans3;
        if(h1<=t1) ans1=q1[h1]+sum;
        else ans1=0;
        if(h2<=t2) ans2=q2[h2]+sum;
        else ans2=0;
        if(h3<=t3) ans3=q3[h3]+sum;
        else ans3=0;
        if(ans1>=ans2&&ans1>=ans3){
            h1++;return ans1;
        }
        if(ans2>=ans1&&ans2>=ans3){
            h2++;return ans2;
        }
        if(ans3>=ans1&&ans3>=ans2){
            h3++;return ans3;
        }
    }
    
    int main(){
        scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
        for(int i=1;i<=n;i++)
        q1[i]=read();
        sort(q1+1,q1+n+1,cmp);
        h1=1,t1=n,h2=h3=1;
        double r=u*1.0/v*1.0;
        for(register int i=1;i<=m;i++){
            LL now=getmax();
            LL res1=floor(r*(now*1.0)),res2=now-res1;
            sum+=q;
            res1-=sum,res2-=sum;
            q2[++t2]=res1,q3[++t3]=res2;
            if(i%t==0) printf("%lld ",now);
        }
        printf("\n");
        for(register int i=h1;i<=t1;i++) ans.push(q1[i]);
        for(register int i=h2;i<=t2;i++) ans.push(q2[i]);
        for(register int i=h3;i<=t3;i++) ans.push(q3[i]);
        for(register int i=1;ans.size();i++){
            if(i%t==0) printf("%lld ",ans.top()+sum);
            ans.pop();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    OK335x mksd.sh hacking
    Qt jsoncpp 对象拷贝、删除、函数调用 demo
    OK335xS 256M 512M nand flash make ubifs hacking
    Qt QScrollArea and layout in code
    JsonCpp Documentation
    Qt 4.8.5 jsoncpp lib
    Oracle数据库生成UUID
    freemarker得到数组的长度
    FreeMarker中if标签内的判断条件
    freemarker语法
  • 原文地址:https://www.cnblogs.com/JoshDun/p/11166761.html
Copyright © 2011-2022 走看看