洛谷P2827 蚯蚓——思路题

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

思路...

用优先队列模拟做的话,时间主要消耗在每次的排序上;

能不能不要每次排序呢?

关注先后被砍的两条蚯蚓 x 和 y,发现砍完以后,它们的两部分对应还满足原来的大小关系!

从两条蚯蚓出发,可以推知所有蚯蚓砍完以后的两部分还对应满足原来的大小关系;

但两部分之间就不一定了;

所以开三个队列,分别记录原来的蚯蚓,砍后第一部分的蚯蚓,砍后第二部分的蚯蚓;

每次取三个队列中最长的蚯蚓砍,砍出来的两部分对应加到砍后的两个队列里;

即使是又砍了已经被砍过的蚯蚓,把它类比成原来的蚯蚓,也满足刚才的那种做法;

于是这题就A了;

有不少细节呢,而且注意要开 long long !以后应该对这些敏感一点;

由这题得到的经验是,遇到关于询问大小关系,没有规律,需要不断排序的问题的时候,关注相邻的两个量的变化关系,也许能有意想不到的发现。

代码如下:

复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
queue<pair<ll,int> >q1,q2,q3;
priority_queue<int>ans;
int const maxn=1e5+5;
int n,m,q,u,v,t,a[maxn];
int main()
{
    scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    for(int i=n;i;i--)q1.push(make_pair(a[i],1));//1
    ll x,x1,x2,x3;
    for(int i=1;i<=m;i++)
    {
        x1=0; x2=0; x3=0;
        if(q1.size()) x1=q1.front().first+q*(i-q1.front().second);
        if(q2.size()) x2=q2.front().first+q*(i-q2.front().second);
        if(q3.size()) x3=q3.front().first+q*(i-q3.front().second);
        if(q1.size() && (!q2.size()||x1>=x2) && (!q3.size()||x1>=x3)) x=x1,q1.pop();//=
        else if(q2.size() && (!q1.size()||x2>=x1) && (!q3.size()||x2>=x3)) x=x2,q2.pop();//else
        else if(q3.size() && (!q1.size()||x3>=x1) && (!q2.size()||x3>=x2)) x=x3,q3.pop();
    
        if(i%t==0)printf("%lld ",x);
        q2.push(make_pair(x*u/v,i+1)); q3.push(make_pair(x-x*u/v,i+1));//i+1
    }
    printf("\n");
    for(int i=1;i<=n+m;i++)
    {
        x1=0; x2=0; x3=0;
        if(q1.size()) x1=q1.front().first+q*(m+1-q1.front().second);
        if(q2.size()) x2=q2.front().first+q*(m+1-q2.front().second);
        if(q3.size()) x3=q3.front().first+q*(m+1-q3.front().second);
        if(q1.size() && (!q2.size()||x1>=x2) && (!q3.size()||x1>=x3)) x=x1,q1.pop();
        else if(q2.size() && (!q1.size()||x2>=x1) && (!q3.size()||x2>=x3)) x=x2,q2.pop();
        else if(q3.size() && (!q1.size()||x3>=x1) && (!q2.size()||x3>=x2)) x=x3,q3.pop();
        
        if(i%t==0)printf("%lld ",x);
    }
    return 0;
}
复制代码

 

posted @   Zinn  阅读(127)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥
点击右上角即可分享
微信分享提示