社区讨论

大佬和蒟蒻都看这里……

P3957[NOIP 2017 普及组] 跳房子参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi85zr97
此快照首次捕获于
2025/11/21 09:11
4 个月前
此快照最后确认于
2025/11/21 09:11
4 个月前
查看原帖

莫名90,最后一点WA了……

CPP
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstdlib>
#include <cstring>

using namespace std;

#define MAXN 500010
#define ll long long
#define INF 0x7fffffff

ll n, d, k, sum, lt, rt, mid, len, ans = -1;
ll dis[MAXN], val[MAXN], f[MAXN], que[MAXN];

bool check(ll dt)
{
    memset(f, 0ll, sizeof(f));
    ll st = max(1ll, d - dt), en = d + dt, l = 1ll, r = 0ll;
    for (int j = 0, i = 1; i <= n; ++ i)
    {
        while (j < i && dis[j] <= dis[i] - st)
        {
            while (l <= r && f[que[r]] < f[j])
                -- r;
            que[++ r] = j ++;
        }
        while (l <= r && dis[que[l]] < dis[i] - en)
            ++ l;
        ll maxn = f[que[l]];
        if (l > r)
            maxn = -INF;
        f[i] = maxn + val[i];
        if (f[i] >= k)
            return 1;
    }
    return 0;
}

int main()
{
    scanf("%lld%lld%lld", &n, &d, &k);
    for (int i = 1; i <= n; ++ i)
    {
        scanf("%lld%lld", &dis[i], &val[i]);
        sum += (val[i] > 0ll ? val[i] : 0ll);
        len = max(len, dis[i]);
    }
    if (sum < k)
        printf("-1"), exit(0);
    lt = 0;
    rt = len;
    while (lt <= rt)
    {
        mid = (lt + rt) >> 1;
        if (check(mid))
            rt = mid - 1ll, ans = mid;
        else 
            lt = mid + 1ll;
    }
    printf("%lld", ans);
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...