zoukankan      html  css  js  c++  java
  • [POI2015]WIL-Wilcze doły

    定义(sum[x] = sum_{i = 1}^x a[i])

    首先不难想到,我们枚举左右端点,然后贪心的减去这一段区间中(sum[x] - sum[x - d + 1])的最大值,这样枚举是(O(N^3))

    然后我们发现,对于一个左端点,我们肯定要尽可能的往后去找右端点,同理,对于一个右端点,我们肯定要尽可能找满足条件的最偏左的左端点

    可以把枚举改成双指针,复杂度变成了(O(N^2))

    我们重新来看一下题意的式子:枚举右端点(r),找到(max(sum[r] - sum[l - 1] - max(sum[x] + sum[x - d + 1])))的值

    我们复杂度的瓶颈在于维护(max(sum[x] + sum[x - d + 1])),不难发现这个式子是单调的,所以我们可以使用单调队列来维护

    右指针每次往右边移动的时候,把(max(sum[x] + sum[x - d + 1]))加入队列并弹出不单调的值

    如果当前队列的最大值(队首)所对应的端点比我们求出的左端点小了,就可以弹出了

    #include<bits/stdc++.h>
    using namespace std;
    #define il inline
    #define re register
    #define int long long
    il int read() {
        re int x = 0, f = 1; re char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
        return x * f;
    }
    #define rep(i, s, t) for(re int i = s; i <= t; ++ i)
    #define maxn 2000005
    int n, p, d, ans, a[maxn], l, sum[maxn], h, t, q[maxn];
    signed main() {
    	n = read(), p = read(), d = read();
    	rep(i, 1, n) a[i] = read(), sum[i] = sum[i - 1] + a[i];
    	ans = d, q[t] = d, l = 1;
    	rep(i, d + 1, n) {
    		while(h <= t && sum[i] - sum[i - d] > sum[q[t]] - sum[q[t] - d]) -- t;
    		q[++ t] = i;
    		while(h <= t && sum[i] - sum[l - 1] - sum[q[h]] + sum[q[h] - d] > p) {
    			++ l;
    			while(h <= t && q[h] - d + 1 < l) ++ h;
    		}
    		ans = max(ans, i - l + 1);
    	}
    	printf("%lld", ans);
    	return 0;
    }
    
  • 相关阅读:
    hdu 1016 Prime Ring Problem (dfs)
    微信小程序尝鲜一个月现状分析
    创新大师Steve Blank: 你真的知道什么是真正的精益创业吗?
    android studio 开发经常使用快捷键使用分享
    LeetCode:Partition List
    2016 博客导读总结 &amp; 个人感悟
    poj
    Android开之在非UI线程中更新UI
    浅谈数据库生命周期
    从AdventureWorks学习数据库建模——保留历史数据
  • 原文地址:https://www.cnblogs.com/bcoier/p/11618374.html
Copyright © 2011-2022 走看看