bzoj4721 [Noip2016]蚯蚓

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4721

【题解】

维护一个全局增量p后就可以用堆来实现操作了。

发现切割成的也满足单调关系,所以直接用三个队列做就行了。

怎么满足啊?观察。。

# include <queue>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;
const ll inf = 1e18;

# define RG register
# define ST static

int n, m, c, u, v, T, a[M];
queue<ll> q1, q2, q3;
ll p = 0;
ll A, B, C;

inline ll gettop() {
    if(q1.empty()) A = -inf;
    else A = q1.front();
    if(q2.empty()) B = -inf;
    else B = q2.front();
    if(q3.empty()) C = -inf;
    else C = q3.front();
    if(A >= B && A >= C) {
        q1.pop();
        return A + p;
    }
    if(B >= A && B >= C) {
        q2.pop();
        return B + p;
    }
    q3.pop();
    return C + p;
}

int main() {
    cin >> n >> m >> c >> u >> v >> T;
    for (int i=1; i<=n; ++i) scanf("%d", &a[i]);
    sort(a+1, a+n+1);
    for (int i=n; i; --i) q1.push((ll)a[i]);
    bool fir = 1; int times = 0;
    for (int i=1; i<=m; ++i) {
        ll x = gettop(), y;
        ++times;
        if(times == T) {
            if(fir) printf("%lld", x), fir = 0;
            else printf(" %lld", x);
            times = 0;
        }
        p += c;
        y = ((double)u/v) * x;
        x = x-y;
        y = y - p;
        x = x - p; 
        q2.push(x); q3.push(y);
    }
    puts("");
    fir = 1; times = 0;
    for (int i=1; i<=n+m; ++i) {
        ll x = gettop();
        ++times;
        if(times == T) {
            if(fir) printf("%lld", x), fir = 0;
            else printf(" %lld", x);
            times = 0;
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/galaxies/p/bzoj4721.html