@bzoj - [email protected] [POI2015] Wilcze do?y

目录

  • @[email protected]
  • @[email protected]
  • @accepted [email protected]
  • @[email protected]

@[email protected]

给定一个长度为 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

@[email protected]

如果选择的区间长度 <= 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 [email protected]

#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);
}

@[email protected]

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

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

时间: 2024-11-08 12:47:02

@bzoj - [email protected] [POI2015] Wilcze do?y的相关文章

@bzoj - [email&#160;protected] [POI2015] Kinoman

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 共有 m 部电影,第 i 部电影的好看值为 w[i]. 在 n 天之中每天会放映一部电影,第 i 天放映的是第 f[i] 部. 你可以选择 l, r (1 <= l <= r <= n) ,并观看第 l, l+1, -, r 天内所有的电影. 最大化观看且仅观看过一次的电影的好

@bzoj - [email&#160;protected] [POI2015] Logistyka

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 维护一个长度为 n 的序列,一开始都是 0,支持以下两种操作: 1.U k a 将序列中第 k 个数修改为 a. 2.Z c s 在这个序列上,每次选出 c 个正数,并将它们都减去 1,询问能否进行 s 次操作. 每次询问独立,即每次询问不会对序列进行修改. input 第一行包含两个

@bzoj - [email&#160;protected] [POI2015] Myjnie

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 有 n 家洗车店从左往右排成一排,每家店都有一个正整数价格 p[i]. 有 m 个人要来消费,第 i 个人会驶过第 a[i] 个开始一直到第 b[i] 个洗车店,且会选择这些店中最便宜的一个进行一次消费.但是如果这个最便宜的价格大于 c[i],那么这个人就不洗车了. 请给每家店指定一个

@bzoj - [email&#160;protected] [POI2015] Odwiedziny

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一棵 n 个点的树,树上每条边的长度都为 1 ,第 i 个点的权值为 a[i]. Byteasar 会按照某个 1 到 n 的全排列 b 走 n-1 次,第 i 次他会从 b[i] 点走到 b[i+1] 点,并且这一次的步伐大小为 c[i]. 对于一次行走,假设起点为 x,终点为

@bzoj - [email&#160;protected] [POI2015] Pustynia

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个长度为 n 的正整数序列 a,每个数都在 1 到 10^9 范围内. 告诉你其中 s 个数,并给出 m 条信息,每条信息包含三个数 l, r, k 以及 k 个正整数,表示 a[l], a[l+1], ..., a[r-1], a[r] 里这 k 个数中的任意一个都比任意一个剩

@bzoj - [email&#160;protected] [POI2015] ?asuchy

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 圆桌上摆放着 n 份食物,围成一圈,第 i 份食物所含热量为 c[i]. 相邻两份食物之间坐着一个人,共有 n 个人.每个人有两种选择,吃自己左边或者右边的食物.如果两个人选择了同一份食物,这两个人会平分这份食物,每人获得一半的热量. 假如某个人改变自己的选择后(其他 n-1 个人的选

@bzoj - [email&#160;protected] [POI2015] Wycieczki

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一张 n 个点 m 条边的带权有向图,每条边的边权只可能是1,2,3中的一种. 将所有可能的路径按路径长度排序,请输出第 k 小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. input 第一行包含三个整数 n, m, k (1<=n<=40,1<=m<

bzoj 4385: [POI2015]Wilcze do?y

4385: [POI2015]Wilcze do?y 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 包含一行一个正整数,即修改后能

@bzoj - [email&#160;protected] [Poi2011]Lightning Conductor

目录 @[email protected] @[email protected] @part - [email protected] @part - [email protected] @part - [email protected] @accepted [email protected] @version - [email protected] @version - [email protected] @[email protected] @[email protected] 已知一个长度为