洛谷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("
");
    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;
}
原文地址:https://www.cnblogs.com/Zinn/p/9215359.html