zoukankan      html  css  js  c++  java
  • P4754 True Vegetable

    题目描述

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

    输入输出格式

    输入格式:

     

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

    第二行输入 NN 个整数 a_1,a_2,cdots,a_Na1,a2,,aN ,分别为 NN 个题目的毒瘤程度。

    第三行输入 LL 个整数 r_1,r_2,cdots,r_Lr1,r2,,rL ,分别为释放 11 到 LL 点菜气的冷却回合数。

    接下来有 MM 行,每行输入三个整数 w_i,x_i,v_iwi,xi,vi ,表示小B在第 w_iwi 回合开始时向第 x_ixi 题释放了 v_ivi 点的菜气。保证 {w_i}{wi} 为递增序列。

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1: 
    6 1 3 2
    0 0 0 0 0 0
    1 2
    2 1 1
    输出样例#1: 
    3
    输入样例#2: 
    6 1 3 2
    1 0 0 0 0 0
    1 2
    2 1 1
    输出样例#2: 
    2
    输入样例#3: 
    6 1 6 2
    0 0 0 0 0 0
    1 2
    2 1 1
    输出样例#3: 
    1

    说明

    1N,M5×105

    1KN

    1L100

    a[i]{0,1}

    1=r1<r2<<rL2×L

    1wiN+L

    wi+rviwi+1

    1xiN

    1viL

     

    Solution:

      本题也是贼有意思,考查细心读题。

      题目中明确的说了$w_i+r_{v_i}leq w_i+1$,于是可以想到,当某个位置的值减少后,完全可以通过冷却的时间来恢复。

      令被减去的时间为时间点,考虑二分被减的时间点,然后将难度先减去要减的值,因为减难度的冷却时间不小于需要加的数量,被减的数量可以用相同数量的时间填补,所以当一个时间点可以达到目标时,下一个时间点必然也能达到目标。

      然后在时间点上计算出需要的时间。二分时间点,在减去生效的操作后,我们可以贪心地从左到右地考虑,当位置$i$小于$1$时,考虑贪心地将$[i,i+k-1]$这个区间加$1$,可以使需要的回合数尽量小。当确定小B有哪些操作生效时,这样就可以求出满足条件的准确最小时间,若这个时间小于下个时间点,那么check()就是有效的。

      时间复杂度$O(nlog n)$

    代码:

     

    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=500005;
    int n,m,k,L,a[N],R[N],tp[N],b[N];
    struct node {
        int w,x,v;
    }t[N];
    
    il int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
        return f?-a:a;
    }
    
    il int check(int mid){
        For(i,1,n) tp[i]=a[i],b[i]=0;
        For(i,1,mid) tp[t[i].x]-=t[i].v;
        int tmp=0,tot=0,dis;
        For(i,1,n){
            if(tp[i]+tmp<1){
                dis=1-tp[i]-tmp;
                tot+=dis;
                b[i]+=dis;
                if(i+k-1<=n) b[i+k-1]-=dis;
            }
            tmp+=b[i];
        }
        return max(t[mid].w,tot);
    }
    
    int main(){
        n=gi(),m=gi(),k=gi(),L=gi();
        For(i,1,n) a[i]=gi(); For(i,1,L) R[i]=gi();
        For(i,1,m) t[i].w=gi(),t[i].x=gi(),t[i].v=gi();
        t[0].w=0,t[m+1].w=233333333;
        int l=0,r=m,mid,ans;
        while(l<=r){
            mid=l+r>>1;
            if(check(mid)<t[mid+1].w) ans=mid,r=mid-1;
            else l=mid+1;
        }
        cout<<check(ans);
        return 0;
    }

     

     

  • 相关阅读:
    分分钟提升命令行模式下密码输入逼格
    MySQL server has gone away 的两个最常见的可能性
    第一次遇到刷新缓冲区延时
    Mac上安装mysqlclient的报错
    python3 --- locale命名空间让程序更加安全了
    doctest --- 一个改善python代码质量的工具
    MySQL优化器 --- index_merge
    机智的MySQL优化器 --- is null
    Centos-7.x 下子网掩码的配置
    JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查
  • 原文地址:https://www.cnblogs.com/five20/p/9352852.html
Copyright © 2011-2022 走看看