码迷,mamicode.com
首页 > 其他好文 > 详细

@bzoj - 4385@ [POI2015] Wilcze do?y

时间:2019-02-06 18:37:20      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:list   队列   return   put   break   amp   bre   lis   name   

@description@

给定一个长度为 n 的序列,你有一次机会选中一段连续的长度不超过 d 的区间,将里面所有数字全部修改为 0。
请找到最长的一段连续区间,使得该区间内所有数字之和不超过 p 。

input
第一行包含三个整数 n, p, d (1 <= d <= n <= 2000000,0 <= p <= 10^16)。
第二行包含n个正整数,依次表示序列中每个数 w[i] (1 <= w[i] <= 10^9)。

output
包含一行一个正整数,即修改后能找到的最长的符合条件的区间的长度。

sample input
9 7 2
3 4 1 9 4 1 7 1 3

sample output
5

@solution@

如果选择的区间长度 <= d,则可以把这个区间改成全零区间,它一定合法。
也就是说最终区间的长度一定 >= d。

如果选择的区间长度 >= d,贪心地想,我们肯定是修改这个区间内长度为 d 且权值和最大的子区间。

我们用 s[l...r] 表示 l ~ r 的权值和。对于每一个 i,我们再记录一个 f[i] = s[i-d+1 ... i]。

如果我们选择了区间 [l, r],它对答案的贡献为 s[l...r] - max{f[l+d-1] ... f[r]}。

使用滑动窗口求解答案,并使用单调队列维护上面的 max。

@accepted code@

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 2000000;
ll S[MAXN + 5], val[MAXN + 5];
inline ll GetSum(int le, int ri) {
    return S[ri] - S[le-1];
}
int que[MAXN + 5], s = 1, t = 0;
int read() {
    int x = 0; char ch = getchar();
    while( ch > ‘9‘ || ch < ‘0‘ ) ch = getchar();
    while( ‘0‘ <= ch && ch <= ‘9‘ ) x = 10*x + ch-‘0‘, ch = getchar();
    return x;
}
int main() {
    int n, d; ll p;
    scanf("%d%lld%d", &n, &p, &d);
    for(int i=1;i<=n;i++)
        S[i] = S[i-1] + read();
    for(int i=d;i<=n;i++)
        val[i] = GetSum(i-d+1, i);
    int ri = d-1, ans = d;
    for(int le=1;ri<n;le++) {
        while( s <= t && que[s]-le+1 <= d )
            s++;
        while( ri < n ) {
            if( ri-le+1 < d || GetSum(le, ri+1) - max(val[que[s]], val[ri+1]) <= p ) {
                ri++;
                while( s <= t && val[que[t]] <= val[ri] )
                    t--;
                que[++t] = ri;
            }
            else break;
        }
        ans = max(ans, ri-le+1);
    }
    printf("%d\n", ans);
}

@details@

垃圾题目居然卡我常数。不写读入优化还过不了……

@bzoj - 4385@ [POI2015] Wilcze do?y

标签:list   队列   return   put   break   amp   bre   lis   name   

原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/10353847.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!