欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[NOIp2016]蚯蚓

程序员文章站 2024-03-20 13:30:10
...

Description

Luogu2827
有一些蚯蚓,每次取出最长的,切成两份,再放回去。求每次取出的蚯蚓长度和最后的所有蚯蚓长度。

Solution

首先可以想到应用堆来解决这个问题。然后,对于蚯蚓的生长,可以视作新蚯蚓的缩短,即两只新蚯蚓的长度各自减去\(q*t\),再取出时加上即可。
但是这样只能得80分。
通过看题解输出中间变量我们可以发现,其实这个题是有单调性的。
若蚯蚓\(A\)\(t_a\)时刻被切开成\(A_1,A_2\),蚯蚓\(B\)\(t_b\)时刻被切开成\(B_1,B_2\),且\(l_A > l_B\),易知\(t_a < t_b\),则\(t\)时刻,\(l_{A_1} = pl_A+q(t-t_a)\)\(l_{B_1} = pl_B+q(t-t_b)\),所以\(l_{A_1} < l_{B_1}\),同理\(l_{A_2} < l_{B_2}\)。分成三个数组存储即可。

Code

#include <queue>
#include <algorithm>
#include <cstdio>

typedef long long ll;
const int N = 7e6 + 10;
const ll INF = 1e16;

struct Heap {
    ll a[N];
    ll sz;
    ll p;
    Heap() : p(1), sz(0) {}
    void push(ll x) {
        a[++sz] = x;
    }
    ll top() {
        return p <= sz ? a[p] : -INF;
    }
    void pop() {
        p++;
    }
} heap[3];
int n, m, q, u, v, t;

bool cmp(const ll &a, const ll &b) {
    return a > b;
}

int main() {
    scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t);
    ll buf;
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &buf);
        heap[0].push(buf);
    }
    std::sort(heap[0].a+1, heap[0].a+n+1, cmp);
    ll a[3], mx = 0, mxp;
    for (int i = 1; i <= m; ++i) {
        mx = -INF; // mark
        for (int j = 0; j < 3; ++j) {
            a[j] = heap[j].top();
            if (a[j] > mx) {
                mx = a[j];
                mxp = j;
            }
        }
        heap[mxp].pop();
        mx = (mx + (i-1)*q);
        if (i % t == 0) printf("%lld ", mx);
        heap[1].push(mx*u/v-i*q);
        heap[2].push(mx-mx*u/v-i*q);
    }
    puts("");
    int i = 0;
    while (1) {
        mx = -INF;
        ++i;
        for (int j = 0; j < 3; ++j) {
            a[j] = heap[j].top();
            if (a[j] > mx) {
                mx = a[j];
                mxp = j;
            }
        } 
        if (mx == -INF) break;
        mx = mx + q * m; 
        if (i % t == 0) printf("%lld ", mx);
        heap[mxp].pop();
    }
    puts("");
    return 0;
}

Note

mark那里一开始写成了=0
有时候可以利用单调性优化很多最值问题
其实\(l_{A_2} < l_{B_2}\)并不是很好证...

转载于:https://www.cnblogs.com/wyxwyx/p/noip201622.html