zoukankan      html  css  js  c++  java
  • 洛谷 P4754 True Vegetable 解题报告

    P4754 True Vegetable

    题目描述

    小A现在有N道题,编号为1,2,⋯,N。每道题的起始毒瘤程度为0或1。在每天,小A可以将编号连续的K道题的毒瘤程度+1。但小B因为本身比较菜,不是很愿意小A出毒瘤题,所以在(w_i)天开始时可以向第(x_i)题传播(v_i)​点的菜气,使得第(x_i)的毒瘤程度减少(v_i)​点(减后可以为负)。这里我们假定菜是有限的,在释放了(v_i)点的菜气后,小B需要至少$ r_{v_i}$个回合不能释放菜气。现在小A知道了小B释放菜气的计划,他想知道他至少需要多少个回合可以使得每道题的毒瘤程度至少为1。

    输入输出格式

    输入格式:

    第一行输入四个整数,N,M,K,L,分别为题目的数量,小B的操作数量,每次连续增加毒瘤程度题目的数量和释放菜气的最大值。

    第二行输入N个整数(a_1,a_2,cdots,a_N),分别为N个题目的毒瘤程度。

    第三行输入L个整数(r_1,r_2,cdots,r_L),分别为释放1到L点菜气的冷却回合数。

    接下来有M行,每行输入三个整数(w_i,x_i,v_i),表示小B在第(w_i)次回合开始时向第(x_i)题释放了(v_i)点的菜气。保证({w_i})为递增序列。

    输出格式:

    请输出小A将每道题的毒瘤程度加到至少为1最少需要的回合数。

    说明

    (1≤N,M≤5×10^5)

    (1 le K le N)

    (1 le L le 100)

    (a[i] in {0,1})

    (1 = r_1 < r_2 < cdots < r_L le 2 imes L)

    (1 le w_i le N+L)

    (w_i+r_{v_i} le w_{i+1})

    (1 le x_i le N)

    (1 le v_i le L)


    我做的第一道的一道二分答案+贪心的题是一个叫丢瓶盖的,其实和这个题差不多。

    但是这个题明显坑很多。。

    月赛的时候,我们机房一直在吵关于B的决策的问题,从期望争到博弈。

    然而第二天早上

    我们发现了(w_i+r_{v_i} le w_{i+1})

    要你这冷却时间有何用???

    冷静下来以后发现真的有用,只是读入后不需要处理而已。

    因为还有一条(1 = r_1 < r_2 < cdots < r_L le 2 imes L),这个保证了二分的正确性。

    我们二分B做到哪一个计划了,由于以上一个条件,我们可以确定如果B这个计划时A目的达成了,在之后A的计划一定可以达成,而如果这时A的计划没有达成,那么之前也没法达成。

    在二分检查的时候,先让B把招数放了,然后我们对A的题目编号从小到大扫描,如果当前毒瘤值小于1,花时间给它加上,用一个外部的差分数组维护偏移量。

    每次的总时间为B下一个招数的时间-1


    Code:

    #include <cstdio>
    #include <cstring>
    const int N=500010;
    int min(int x,int y){return x<y?x:y;}
    int n,m,k,L,ans;
    //题目的数量,小B的操作,每次连续增加毒瘤程度题目的数量和释放菜气的最大值
    int s[N],tmp[N];//毒瘤值
    int d[N],add;//外界差分数组
    int w[N],x[N],v[N];//w天对x题放了v的菜气
    bool check(int c)
    {
        memset(d,0,sizeof(d));
        add=0;
        for(int i=1;i<=n;i++)
            tmp[i]=s[i];
        for(int i=1;i<=c;i++)
            tmp[x[i]]-=v[i];
        int cnt=w[c+1]-1;
        for(int i=1;i<=n;i++)
        {
            add+=d[i];
            tmp[i]+=add;
            if(tmp[i]<1)
            {
                add+=1-tmp[i];
                d[min(i+k,n+1)]-=1-tmp[i];
                cnt-=1-tmp[i];
                if(cnt<0) return false;
            }
        }
        ans=w[c+1]-1-cnt;
        return true;
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&k,&L);
        for(int i=1;i<=n;i++)
            scanf("%d",s+i);
        for(int i=1;i<=L;i++)
            scanf("%d",s);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",w+i,x+i,v+i);
        w[m+1]=w[m]+N;
        int l=0,r=m;
        while(l<r)
        {
            int mid=l+r>>1;
            if(check(mid))
                r=mid;
            else
                l=mid+1;
        }
        check(l);
        printf("%d
    ",ans);
        return 0;
    }
    
    

    2018.7.15

  • 相关阅读:
    复制某文件夹及其子文件夹中的一定大小的文件
    一个简单的查询脚本
    写一个交互的脚本
    nginx+php5.6.12+discuz
    curl 错误
    python 交互界面tab补全
    uwsgi.xml
    supervisorctl
    认识nginx配置文件
    nginx+uwsgi+django 配置3
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9312173.html
Copyright © 2011-2022 走看看