• Codeforces Round #262 (Div. 2)C(二分答案,延迟标记)


    这是最大化最小值的一类问题,这类问题通常用二分法枚举答案就行了。

    二分答案时,先确定答案肯定在哪个区间内。然后二分判断,关键在于怎么判断每次枚举的这个答案行不行。

    我是用a[i]数组表示初始时花的高度,b[i]表示要达到当前枚举的答案(即mid的值)需要这朵花再涨多少。这两个数组很好算,关键是一次浇连续的w朵花,如何更新区间(暴力的O(n2)的去更新就超时了)?可以用线段树,但是这道题没有涉及区间查询,就是在一个数组上更新区间,用线段树未免小题大做。那么其实这种更新就用延迟标记的思想(懒操作)就可以O(n)的解决了。具体方法参见这道很裸的题:hdu4970

    lazy[]这个标记数组的作用其实就是能记录更新区间到哪里停止.

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    #define INF 1000000000
    #define eps 1e-8
    #define pii pair<int,int>
    #define LL long long int
    const int maxn=110009;
    int n,m,w,a[maxn],b[maxn],lazy[maxn],ans=0;
    /*lazy[]这个标记数组的作用其实就是能记录更新区间到哪里停止*/
    int main()
    {
        //freopen("in6.txt","r",stdin);
        scanf("%d%d%d",&n,&m,&w);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        int l=1,r=maxn+INF,mid;
        while(l<=r)
        {
            memset(lazy,0,sizeof(lazy));
            mid=(r+l)/2;
            for(int i=1; i<=n; i++) b[i]=max(0,mid-a[i]);
            int tm=m,x=0;
            for(int i=1;i<=n;i++)//开始浇水
            {
                x+=lazy[i];//要先看这一步是不是有标记
                b[i]-=x;//把前面对影响到当前b[i]的浇水操作浇上
                if(b[i]>0)//还大于0,那么就必须要从它开始再来一段浇水了
                {
                    tm-=b[i];
                    if(tm<0) break;//天数限制到了
                    lazy[i+w]-=b[i];
                    x+=b[i];
                }
            }
            if(tm<0) r=mid-1;
            else
            {
                ans=mid;
                l=mid+1;
            }
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    Codeforces 120F Spiders
    Codeforces 509C Sums of Digits
    Topcoder SRM 497 DIV2 1000 MakeSquare
    codeforces 22B Bargaining Table
    Codeforces 487B Strip
    Codeforces 132C Logo Turtle
    关闭窗口对话框提示 messagedlg应用和showmodal的使用
    如何让窗口显示在电脑屏幕中间
    delphi项目程序输出编译成应用程序文件
    delphi程序项目创建和保存
  • 原文地址:https://www.cnblogs.com/zywscq/p/3940204.html
Copyright © 2020-2023  润新知