萌新求助2D
  • 板块学术版
  • 楼主Black_Porridge
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/1/15 18:03
  • 上次更新2023/10/24 04:06:47
查看原帖
萌新求助2D
200060
Black_Porridge楼主2023/1/15 18:03

萌新求助,赛时 20pts。

做法是在枚举左端点后,先考虑答案段选不满 kk11 的情况,用单调队列维护 sumi+havisum_i+hav_i;再考虑选满 kk11 之后和最大的一个前缀 。其中 sumisum_i 表示原数组的前缀和, havihav_i 表示 [1,i][1, i] 中总共出现了几个 00

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e7 + 10;

int n, k, l, r, ans, tot;
int q1[N], q2[N];
int a[N], maxn[N], sum[N], is[N], hav[N];
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> k;
    l = 1, memset(maxn, -0x3f, sizeof(maxn));
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    for(int i = 1; i <= n; i++) {
        sum[i] = sum[i - 1] + a[i], is[i] = is[i - 1] + (a[i] == 1 ? 1 : -1);
        if(!a[i])
            maxn[++tot] = sum[i];
        maxn[tot] = max(maxn[tot], sum[i]), hav[i] = tot;
    }
    for(int i = n; i >= 1; i--) {
        while(l <= r && q1[l] > hav[i] + k - (a[i] == 0))
            l++;
        //cout << l << " " << r << " " << q2[l] << " " << hav[i] << " " << sum[i - 1] << " " << a[i] << endl;
        if(l <= r)
            ans = max(ans, q2[l] - hav[i] + (a[i] == 0) - sum[i - 1]);
        if(a[i])
            continue;
        while(l <= r && maxn[hav[i] + hav[i]] > q2[r])
            r--;
        q1[++r] = hav[i], q2[r] = maxn[hav[i]] + hav[i];
    }
    //cout << ans << endl;
    l = -2147483647, r = 0;
    for(int i = n; i >= 1; i--) {
        if(is[i] > l)
            l = is[i], r = i;
       // cout << l << " " << r << " " << l - is[i - 1] + 2 * max(hav[r] - hav[i], k) << endl;
        ans = max(ans, l - is[i - 1] + 2 * min(hav[r] - hav[i] + (a[i] == 0), k));
    }
    cout << ans;
    return 0;
}
2023/1/15 18:03
加载中...