zoukankan      html  css  js  c++  java
  • LUOGU P2827 蚯蚓 (noip 2016)

    传送门

    解题思路

    第一眼以为是一个二叉堆,直接上优先队列60分。。。后来听ztz11说有单调性,新加入的蚯蚓一定比原先在的蚯蚓长度长,开三个队列,分别放原先的长度,切掉后大的那一半,切掉后小的那一半。假设原先的第一个数为x1,第二个数为x2,x1>x2,那么取出x1后大的那一半记做x1*p(假设p>1/2) ,第二个数此时加q,第二次再将第二个数拿出来,大的那一半就是(x2+q)*p=x2*p+q*p,而原先第一个数大的那一半变成了x1*p+q,因为x1>x2,p<0,所以符合单调性。所以只需要每次取出最大的切,然后分成两半分别放入第二个与第三个队列。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    
    typedef long long LL;
    using namespace std;
    const int MAXN = 1e5+5;
    const LL inf = 1e18+5;
    const int MAXM = 7e6+5;
    
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,m,q,u,v,t;
    LL ans[MAXM],a[MAXN];
    queue<LL> Q[4];
    
    inline bool cmp(int x,int y){
        return x>y;
    }
    
    int main(){
    //  freopen("rand.txt","r",stdin);
    //  freopen("A.txt","w",stdout);
        n=rd();m=rd();q=rd();u=rd();v=rd();t=rd();
        for(register int i=1;i<=n;i++) a[i]=rd();
        sort(a+1,a+1+n,cmp);
        for(register int i=1;i<=n;i++) Q[1].push(a[i]);
        for(register int i=1;i<=m;i++){
            LL x=-inf,y=-inf,z=-inf;
            if(Q[1].size()) x=Q[1].front();
            if(Q[2].size()) y=Q[2].front();
            if(Q[3].size()) z=Q[3].front(); 
            LL mx=x;int r=1;
            if(y>mx) mx=y,r=2;
            if(z>mx) mx=z,r=3;Q[r].pop();
            mx+=(LL)(i-1)*q;ans[i]=mx;
            LL now=mx;mx=mx*u/v;now=now-mx;
            Q[2].push(max(now,mx)-(LL)i*q);
            Q[3].push(min(now,mx)-(LL)i*q);
        }
        for(register int i=t;i<=m;i+=t) printf("%lld ",ans[i]);
        puts("");int yy=1;
        for(register int i=1;i<=n+m;i++){
            LL x=-inf,y=-inf,z=-inf;
            if(Q[1].size()) x=Q[1].front();
            if(Q[2].size()) y=Q[2].front();
            if(Q[3].size()) z=Q[3].front();     
            LL mx=x;int r=1;
            if(y>mx) mx=y,r=2;
            if(z>mx) mx=z,r=3;Q[r].pop();
    //      cout<<mx+(LL)q*m<<" ";
            if(yy<t) {yy++;continue;}
            yy=1;printf("%lld ",mx+(LL)m*q);
        }
        return 0;
    }
  • 相关阅读:
    SlideShowExtender制作相册
    Response.Redirect(),Server.Transfer(),Server.Execute()的区别
    虚方法,抽象类,多态性
    gridview获取当前行索引的方法
    AutoQueryTextBox(AjaxPro.dll)非常值得研究的javascript代码
    abstract & virtual & override & new比较(转)
    Asp.net技巧:gridview获取当前行索引的方法
    js 获取浏览器高度和宽度值
    深入理解abstract class和interface
    c++ 静态数据成员和静态成员函数
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676922.html
Copyright © 2011-2022 走看看