【Luogu】P2827蚯蚓(堆转队列)

按照国际惯例先发题目链接?

woc从4月就开始做这sb题。最开始30分升到65分不管了,直到最近几天升到85分,再到今天AC。激动的心情自然是那些一遍就A或者一小时以内就A的神犇难以想象的。

下面说说主要几个分段。

# 35分

按题意用堆模拟。每次暴力修改蚯蚓长度,于是get皮肤:TLE蓝。

# 65分

 考虑到暴力修改消耗的时间复杂度过大,于是考虑偷懒。既然我们不能暴力增长已经存进堆的蚯蚓长度,那就剪短将要存进堆的蚯蚓长度。将目前蚯蚓增加的长度记为mark,从堆里取出来的蚯蚓长度+mark,要存进堆的蚯蚓长度-mark再-q。每次循环mark+=q。

# 100分

先忽略mark和q。蚯蚓肯定是越切越短,那我们还用堆干嘛?直接开三个队列存蚯蚓,第一个队列存输入的蚯蚓,对于切出来的每条蚯蚓,长的放第二个队列,短的放第三个队列。

可以得到三个队列都是单调递减的。取出的蚯蚓从三个队列的队头取最大的。这样就转化为普通队列解法。

代码如下

#include<iostream>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;

bool cmp(int a,int b){return a>b;}

inline long long read(){
long long num=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
    if(ch==‘-‘)f=-1;
    ch=getchar();
}
while(isdigit(ch)){
    num=(num<<1)+(num<<3)+ch-‘0‘;
    ch=getchar();
}
return num*f;
}

inline long long swap(long long a,long long b){long long temp=a;a=b;b=temp;}

long long mark;

long long n,m,q,u,v,t;
long long que[10000000];
long long f[10000000],d[10000000],fh=1,dh=1,ft,dt,qt=1;

int main(){
n=read();m=read();q=read();u=read();v=read();t=read();
for(int i=1;i<=n;++i)que[i]=read();
sort(que+1,que+n+1,cmp);
for(int i=1;i<=m;++i){
    long long data=-1000000000;
    if(data<que[qt]&&qt<=n)data=que[qt];
    if(data<f[fh]&&ft-fh>-1)data=f[fh];
    if(data<d[dh]&&dt-dh>-1)data=d[dh];

    if(data==que[qt]&&qt<=n)qt++;
    else if(data==f[fh]&&ft-fh>-1)fh++;
    else if(dt-dh>-1)dh++;

    data+=mark;
    long long a=data*u/v;
    long long b=data-a;
    if(a<b)swap(a,b);
    f[++ft]=a-mark-q;
    d[++dt]=b-mark-q;
    if(!(i%t))printf("%lld ",data);
    mark+=q;
}
printf("\n");
for(int i=1;i<=n+m;++i){
    long long data=-1000000000;
    if(data<que[qt]&&qt<=n)data=que[qt];
    if(data<f[fh]&&ft-fh>-1)data=f[fh];
    if(data<d[dh]&&dt-dh>-1)data=d[dh];

    if(data==que[qt])qt++;
    else if(data==f[fh]&&ft-fh>-1)fh++;
    else if(dt-dh>-1)dh++;

    data+=mark;
    if(!(i%t))printf("%lld ",data);
}
return 0;
}
时间: 2024-10-26 14:39:35

【Luogu】P2827蚯蚓(堆转队列)的相关文章

Luogu P2827 蚯蚓(模拟)

P2827 蚯蚓 题意 题目描述 本题中,我们将用符号\(\lfloor c\rfloor\)表示对\(c\)向下取整,例如:\(\lfloor 3.0\rfloor =\lfloor 3.1\rfloor =\lfloor 3.9\rfloor =3\). 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现在共有\(n\)只蚯蚓(\(n\)为正整数).每只蚯蚓拥有长度,我们设第\(i\)只蚯蚓的长度为\(a_i(i=1,2,\dots

Luogu P2827 蚯蚓

看到题目就可以想到直接开的堆模拟的过程了吧,这个还是很naive的 注意在用堆做的时候也是要明智一点的,对于蚯蚓长度的相加肯定不能直接遍历并加上,还是可以差分一下的 其实说白了就是把集体加->单体减的一个小技巧,还是挺常用的. 然后看这个数据范围猜想应该是有什么\(O(n)\)的做法的,然后这就要发现题目中隐含的单调性 我们考虑讲所有的蚯蚓分个类,所有初始时没切割过的蚯蚓分为一类,每次切割产生的较长的蚯蚓分为一类,而产生的较短的蚯蚓分为一类 然后我们推到一下就可以发现,对于后面的两类蚯蚓,它们满

做题记录:P2827 蚯蚓

P2827 蚯蚓 AC代码: /* 思路:三队列模拟. 第一个队列存放原始的蚯蚓长度(已从大到小排序). 第二个队列存放蚯蚓被切后的一份的长度([px]). 第三个队列存放蚯蚓被切后的另一份的长度(x-[px]). 每次在三个队列的队头中取一个最大值并将其出队,然后将其分成两份分别存在第二.三个队列里. 因为每一次我们都是切最长的,而当我们切下一条时两条原来属于上一条的蚯蚓又会增长, 所以先切一定大于后切的,第二.三个队列也就是单调递减的了. 除此之外,还要加一个标记,记录当前每一条蚯蚓应增加的

前端进击的巨人(二):栈、堆、队列、内存空间

面试经常遇到的深浅拷贝,事件轮询,函数调用栈,闭包等容易出错的题目,究其原因,都是跟JavaScript基础知识不牢固有关,下层地基没打好,上层就是豆腐渣工程,新人小白,踏实踩土才是关键. 打地基第二篇:本篇我们将对JavaScript数据结构的知识点详解一二. JavaScript中有三种数据结构: 栈(stack) .堆(heap). 队列(queue). 栈(stack) 栈的特点是"LIFO,即后进先出(Last in, first out)".数据存储时只能从顶部逐个存入,取

[luoguP2827] 蚯蚓(堆?队列!)

传送门 35分做法 用堆来取最大值,暴力更新其余数的值. 65~85分做法 还是用堆来取最大值,其余的数增加可以变成新切开的两个数减少,最后统一加上一个数. #include <queue> #include <cstdio> #include <iostream> #include <algorithm> #define LL long long LL q, u, v; int n, m, t; std::priority_queue <LL>

luogu 2827 蚯蚓 单调队列/优先队列

易知可利用优先队列选取最大值: 但是通过分析可知,先取出的蚯蚓分开后仍然要比后分的长,所以可直接利用单调队列找队头即可,分三个单调队列,分别找未切割,切割,切割2三种情况 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) #define ll long long using namespace std; const int inf=2147483647; const int N=1e5+5;

[Noip2016]蚯蚓 D2 T2 队列

[Noip2016]蚯蚓 D2 T2 Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓.蛐蛐国里现在共有n只蚯蚓(n为正整 数).每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可 能存在长度为0的蚯蚓).每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任

洛谷 P2827 蚯蚓

题目描述 本题中,我们将用符号\lfloor c \rfloor⌊c⌋表示对c向下取整,例如:\lfloor 3.0 \rfloor= \lfloor 3.1 \rfloor=\lfloor 3.9 \rfloor=3⌊3.0⌋=⌊3.1⌋=⌊3.9⌋=3. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现在共有n只蚯蚓(n为正整数).每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n)a?i??(i=1,2,..

P2827 蚯蚓

暴力出奇迹!!! 昨晚很积极地拿手机看这道题的题面,还挺易懂的. 然后写了第二发程序,用优先队列再弄个delta轻轻松松85pts... 要是过几天考试能像这样该多好啊... 显然那个人挑出所有蚯蚓的最长的,就是堆的基本操作了. 然后想到没有挑出来的蚯蚓是会长长的,但是他们已经在堆里面,用优先队列不可能去修改他们啊! 其实直接维护个变量就可以了. 加新的蚯蚓就要记得减掉这个delta,把蚯蚓拿出来就记得加上这个delta,然后就没问题了. 所以轻松地拿到85pts... 为什么不能满分?因为这个