zoukankan      html  css  js  c++  java
  • 【题解】洛谷P2827 [NOIP2016TG] 蚯蚓(优先队列)

    题目来源:洛谷P2827

    思路

    阅读理解题

    一开始以为是裸的优先队列而已

    但是发现维护一个切开并且其他的要分别加上一个值很不方便

    而且如果直接用优先队列会TLE3到4个点 自测85分

    所以我们需要发现题目中蕴含的单调性(我才不会说是从题解中发现的呢)

    来自你谷aiyougege大佬的证明:

    先被切掉的蚯蚓分成的蚯蚓一定比后切掉的蚯蚓分成的蚯蚓大. 假设这两只蚯蚓分别为a,b 

    其中a>b 那么它被切成a1,a2.t秒后, b被切成了b1,b2.

    此时a1,a2的长度为​La1*p+t,La2*(1-p)+t   b1,b2的长度为p*(Lb1+t),(1-p)(Lb2+t)

    因为p小于1 所以a1>b1,a2>b2

    也就是说根本不需要用一个堆来维护, 它本来就具有一定单调性.

    所以我们只需要开三个队列来分别存下一开始的单调序列(sort一遍)q1 每次切割的较大的长度q2 每次切割的较小的长度q3

    这样三个队列就都是单调的了

    所以我们每次只需要找出三个队列中的队首最大值来切割

    然后把切割的较大值放入q2 较小值放入q3即可

    现在需要思考如何让蚯蚓生长

    如果每次切割之后把其他蚯蚓遍历一遍肯定不现实

    所以我们考虑直接在要切割的蚯蚓长度减去其他蚯蚓要增加的长度 

    那么从相对的角度来说 其他的蚯蚓就算是生长了

    我们只需要记录这个减去的长度 后面再加上即可

    代码

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue> 
    using namespace std;
    #define maxn 7500000
    #define ll long long 
    ll n,m,q,u,v,t,add,tot;
    ll ans[maxn],len[maxn];
    queue<int> q1,q2,q3;
    bool cmp(int x,int y)
    {
        return x>y;
    }
    ll getmax()//取最大值 
    {
        ll x1,x2,x3;
        x1=x2=x3=-1e9+7;
        if(!q1.empty()) x1=q1.front();
        if(!q2.empty()) x2=q2.front();
        if(!q3.empty()) x3=q3.front();
        if(x1>=x2&&x1>=x3)
        {
            q1.pop();
            return x1;
        }
        if(x2>=x1&&x2>=x3)
        {
            q2.pop();
            return x2;
        }
        if(x3>=x2&&x3>=x1)
        {
            q3.pop();
            return x3;
        }
    }
    void put(ll x,ll y)//比较放入队列 
    {
        if(x<y) swap(x,y);
        q2.push(x);
        q3.push(y);
    }
    int main()
    {
        cin>>n>>m>>q>>u>>v>>t;
        for(ll i=1;i<=n;i++) cin>>len[i];
        sort(1+len,1+len+n,cmp);//维护q1单调性 
        for(ll i=1;i<=n;i++) q1.push(len[i]);
        for(ll i=1;i<=m;i++)
        {
            ans[i]=getmax()+add;//add为相对增加值 
            ll x=ans[i]*u/v;//计算被切割开的长度 
            ll y=ans[i]-x;
            add+=q;//增加相对值 
            put(x-add,y-add);//注意这里要减去蚯蚓长度 
        }
        while(!q1.empty()||!q2.empty()||!q3.empty())//最后剩下的蚯蚓按降序存储 
        len[++tot]=getmax()+add;
        for(ll i=t;i<=m;i+=t)//注意输出方式 
        cout<<ans[i]<<" ";
        cout<<endl;
        for(ll i=t;i<=tot;i+=t)//注意输出方式 
        cout<<len[i]<<" ";
        cout<<endl;
    }
  • 相关阅读:
    springmvc 拦截器
    springmvc 文件上传
    springmvc 数据验证 hibernate-validator --->对象验证
    springmvc 类型转换器 数据回显及提示信息
    springmvc框架自带的异常处理器SimpleMappingExceptionResolver的使用
    如何解决JSP页面顶端报错 The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    eval函数的使用之一
    【模板】负环判定
    【洛谷P1072】Hankson 的趣味题
    【洛谷P1463】反素数
  • 原文地址:https://www.cnblogs.com/BrokenString/p/9866857.html
Copyright © 2011-2022 走看看