1 条题解

  • 0
    @ 2025-10-17 18:32:17

    题解

    「蚯蚓」模拟的核心是维护当前长度的最大值,并把它按比例拆成两段。直接使用优先队列会超时,因此代码将三个来源的队列分离,并用指针和懒加值来维护:

    1. 初始化:读入初始长度数组 a 并按降序排序。bc 分别存放拆分后产生的两段。
    2. 懒标记:由于每经过一次操作,所有蚯蚓都会统一加上 q,程序在取出最大值时临时加上 (i-1)*q,并在把新段放入 bc 时再减去当前的增量,等到后续取出时补回即可。
    3. 多路合并:用三个指针 la,lb,lcla,lb,lc 指向目前仍未取走的段,每次比较三者的真实长度(考虑懒加值)选出最大的那条蚯蚓。把长度 l 按比例拆成 l*u/vl - l*u/v 两条,分别放进 bc 的末尾。
    4. 输出:每经过 t 次操作输出一次当前取出的长度;最后还要把所有剩余的段(包括 bc 中的)按取出的顺序补齐输出,同样需要补上总共增加的 m*q

    由于每条蚯蚓最多被拆一次,整个过程只在数组上前移指针,时间复杂度 \(O((n+m)\ log(n+m))\)≈\(O(n+m)\),可以满足数据范围。

    #include<cstdio>
    using namespace std;
    long long n,m,q,u,v,t,a[200000],b[7100000],c[7100000],qq[200000],la,ra,lb,rb,lc,rc,i,l,aa,bb,p;
    void sort(int l,int r)
    {
    	int i=l,j,k=l,mid=(l+r)/2;
    	j=mid+1;
    	if(l==r)
    	{
    		qq[l]=a[l];
    		return;
    	}
    	sort(l,mid);
    	sort(mid+1,r);
    	while(i<=mid&&j<=r)
    	{
    		if(qq[i]>=qq[j])
    		{
    			a[k]=qq[i];
    			i++;
    		}
    		else
    		{
    			a[k]=qq[j];
    			j++;
    		}
    		k++;
    	}
    	while(i<=mid)
    	{
    		a[k]=qq[i];
    		i++;
    		k++;
    	}
    	while(j<=r)
    	{
    		a[k]=qq[j];
    		j++;
    		k++;
    	}
    	for(i=l;i<=r;i++)
    	qq[i]=a[i];
    }
    main()
    {
    	scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&q,&u,&v,&t);
    	la=1;
    	ra=n;
    	lb=1;
    	lc=1;
    	for(i=1;i<=n;i++)
    	scanf("%lld",&a[i]);
    	sort(1,n);
    	for(i=1;i<=m;i++)
    	{
    		l=-1000000000000;
    		if(ra>=la&&a[la]>=l)
    		{
    			l=a[la];
    			p=1;
    		}
    		if(rb>=lb&&b[lb]>=l)
    		{
    			l=b[lb];
    			p=2;
    		}
    		if(rc>=lc&&c[lc]>=l)
    		{
    			l=c[lc];
    			p=3;
    		}
    		l=l+(i-1)*q;
    		aa=l*u/v;
    		bb=l-aa;
    		if(i%t==0)
    		printf("%lld ",l);
    		rb++;
    		b[rb]=aa-i*q;
    		rc++;
    		c[rc]=bb-i*q;
    		if(p==1)
    		la++;
    		if(p==2)
    		lb++;
    		if(p==3)
    		lc++;
    	}
    	printf("\n");
    	for(i=1;i<=n+m;i++)
    	{
    		l=-1000000000000;
    		if(ra>=la&&a[la]>=l)
    		{
    			l=a[la];
    			p=1;
    		}
    		if(rb>=lb&&b[lb]>=l)
    		{
    			l=b[lb];
    			p=2;
    		}
    		if(rc>=lc&&c[lc]>=l)
    		{
    			l=c[lc];
    			p=3;
    		}
    		l=l+m*q;
    		if(i%t==0)
    		printf("%lld ",l);
    		if(p==1)
    		la++;
    		if(p==2)
    		lb++;
    		if(p==3)
    		lc++;
    	}
    }
    
    • 1

    信息

    ID
    3237
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    1
    已通过
    1
    上传者