zoukankan      html  css  js  c++  java
  • BZOJ4385: [POI2015]Wilcze doły

    首先肯定删 d 个是最优的

    假设当前选出的区间为 [l,r] ,删去的一定是和最大的子串

    把每个位置的值换成从当前位置向前长度d的区间的和

    删的一定是最大的位置

    随着区间右端点的移动,左端点是单调不降的

    可以维护两个指针,再找一个东西求区间最大值就行了

    由于区间端点都是单调的,所以可以单调队列做,
    枚举右端点维护左端点,每次取队头作为删掉的部分
    当删掉最大的区间后和还是大于给定值时,就移动左端点

    如何检查队头的合法性?

    由于最开始显然的性质,每次删去一段长度为 d 的区间
    那么如果 队头位置 - d < l 了就不符合前边的做法了,
    在这样的不合法的前提下如果每次删去的区间和左端点取 max 的话在之前是没有问题的
    等到左端点超过队头就该 GG 了


     代码:

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cctype>
    #include <cstdio>
    using namespace std;
     
    typedef long long ll;
    const int MAX_N = 2000005;
     
    int n, d, hd, tl, ans;
    ll p;
    int num[MAX_N];
    ll pre_sum[MAX_N], sig_d[MAX_N];
    int q[MAX_N];
     
    inline int rd() {
        register int x = 0, c = getchar();
        while (!isdigit(c)) c = getchar();
        while (isdigit(c)) {
            x = x * 10 + (c ^ 48);
            c = getchar();
        }
        return x;
    }
    inline ll rd_ll() {
        register ll x = 0;
        register int c = getchar();
        while (!isdigit(c)) c = getchar();
        while (isdigit(c)) {
            x = x * 10ll + (c ^ 48);
            c = getchar();
        }
        return x;
    }
     
    int main() {
        n = rd(); p = rd_ll(); d = rd();
        for (int i = 1; i <= n; ++i) {
            num[i] = rd();
            pre_sum[i] = pre_sum[i - 1] + num[i];
            sig_d[i] = pre_sum[i] - pre_sum[(i > d) ? (i - d) : 0];
        }
        ans = d;
        register int bgn = 1;
        tl = 1;
        q[++hd] = d;
        for (int i = d + 1; i <= n; ++i) {
            while (hd <= tl && sig_d[i] >= sig_d[q[tl]]) --tl;
            q[++tl] = i;
            while (hd <= tl && pre_sum[i] - pre_sum[bgn - 1] - sig_d[q[hd]] > p) {
                ++bgn;
                while (hd <= tl && q[hd] - d + 1 < bgn) ++hd;
            }
            ans = max(ans, i - bgn + 1);
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    msyqld 的 The user specified as a definer ('root'@'%') does not exist 问题
    Python加密模块-pycryptodome
    【leetcode 简单】 第一百一十题 分发饼干
    Python数据类型-字典
    Python数据类型-集合(set)
    Python数据类型-列表(list)增删改查
    Python数据类型-元组
    Python 函数系列- Str
    Linux运维之shell脚本
    python之面向对象篇6
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9885988.html
Copyright © 2011-2022 走看看