[NOIp2016]蚯蚓

[NOIp2016]蚯蚓

Description

一共有n只蚯蚓,每只蚯蚓有一个长度,并且蚯蚓会按每年q厘米的速度增长。

现在每年选择一只最长的蚯蚓,将其按p的比例切成两半,被切的的蚯蚓这一年不能增长,问每年被切的蚯蚓的长度和m年后所有蚯蚓的长度

Solution

发现蚯蚓每年长度都会改变,很难处理

但实际上每年只有被切断的蚯蚓不会增长,所以可以考虑维护一个增加值的tag,这样就可以那一个堆来维护最大的蚯蚓

但是这样并不能过这道题

我们考虑优化这个做法,容易发现这个做法的复杂度瓶颈在于用堆维护当前时间最大蚯蚓是哪个

考虑到每次拿出去切的蚯蚓不会改变其他没被切的蚯蚓的大小关系

而且切的比例一定,于是新增的两条蚯蚓长度一点是递减的

于是拿三个队列维护一波就行了

#include<bits/stdc++.h>

using namespace std;

#define LL long long

inline LL read()
{
    LL f = 1 , x = 0;
    char ch;
    do
    {
        ch = getchar();
        if(ch=='-') f=-1;
    } while(ch<'0'||ch>'9');
    do
    {
        x=(x<<3) + (x<<1) + ch - '0';
        ch = getchar();
    }while(ch>='0'&&ch<='9');
    return f*x;
}

const int MAXN = 100000 + 5;

queue<LL>Q[4];
int n,m,q,u,v,t;
LL a[MAXN];
double p;
LL add;

inline bool cmp(int a1,int a2)
{
    return a1 > a2;
}

inline int check()
{
    int res = 1;
    while(!Q[res].size()) res++;
    for(int i=res+1;i<=3;i++) if(Q[i].size()&&Q[i].front() > Q[res].front()) res = i;
    return res;
}

int main()
{
    n = read(),m = read(),q = read(),u = read(),v = read();t = read(); 
    p = 1.0 * u / v;
    for(int i=1;i<=n;i++) a[i] = read();
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++) Q[1].push(a[i]);
    for(int i=1;i<=m;i++)
    {
        int cur = check();
        if(i % t == 0) printf("%lld ",Q[cur].front() + add);
        LL res = Q[cur].front();Q[cur].pop();
        LL Cut = (res + add) * u / v;
        LL res1 = Cut - add - q,res2 = res - Cut - q;
        Q[2].push(res1);Q[3].push(res2);
        add += q;
    }
    printf("\n");
    for(int i=1;i<=n+m;i++)
    {
        int cur = check();
        if(i % t == 0) printf("%lld ",Q[cur].front() + add);
        Q[cur].pop();
    }
}

 

posted @ 2020-11-24 20:37  wlzs1432  阅读(117)  评论(0编辑  收藏  举报