【JZOJ4907】蚯蚓

本文详细解析了一种基于队列的算法,用于解决蚯蚓切割问题。通过将蚯蚓按长度降序排列并使用三个队列,算法能够高效地确定每次切割后的最长蚯蚓部分。该方法不仅适用于暴力堆策略,而且提供了更优的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

description


analysis

  • 暴力堆是部分分,但正解是乱搞

  • 可以证明或者脑补出来,先被砍半的蚯蚓的两部分一定比后砍半的蚯蚓的两部分要先砍

  • 因为先砍的蚯蚓本来就比后面的蚯蚓长,所以各砍半后也是前面的蚯蚓的两部分长

  • 所以用三个队列,第一个队列存下原来的数组降序排列

  • 每次取出三个队列的队头的最大值,砍半之后塞到第二、三个队列里就可以了


code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 10000005
#define INF 1000000007
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)

using namespace std;

ll a[3][MAXN],top[3],len[3];
ll n,m,q,u,v,t,mx,where;

inline bool cmp(ll x,ll y)
{
	return x>y;
}
inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int main()
{
	//freopen("readin.txt","r",stdin);
    freopen("earthworm.in","r",stdin);
   	freopen("earthworm.out","w",stdout);
    n=read(),m=read(),q=read(),u=read(),v=read(),t=read();
    fo(i,1,n+m)a[0][i]=a[1][i]=a[2][i]=-INF;
    fo(i,1,n)a[0][i]=read();
    sort(a[0]+1,a[0]+n+1,cmp);
    top[0]=top[1]=top[2]=1,len[0]=n;
    fo(i,1,m)
    {
        mx=-INF;
        fo(j,0,2)if(a[j][top[j]]>mx)mx=a[j][top[j]],where=j;
        mx+=(i-1)*q,++top[where];
        if (i%t==0)printf("%lld ",mx);
        ll x=mx*u/v,y=mx-x;
        a[1][++len[1]]=x-i*q,a[2][++len[2]]=y-i*q;
    }
    printf("\n");
    fo(i,1,n+m)
    {
        mx=-0x7fffffff;
        fo(j,0,2)if(a[j][top[j]]>mx)mx=a[j][top[j]],where=j;
        mx+=m*q,++top[where];
        if (i%t==0)printf("%lld ",mx);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值