一二三四五 上山打老虎

NC14583-糖糖别胡说,我真的不是签到题目

题目链接:https://ac.nowcoder.com/acm/problem/14583

题意:好复杂,不全部复述了,两个操作如下:
一:第i秒 糖糖i会消灭某些糖糖
二:第i秒发功会使b1 ~ bi 都增加1
然后计算最后剩余多少个糖糖

思路:暴力枚举+前缀和优化
对于操作一:倒着遍历,如果当前糖糖后有个另外组的糖糖功力值比他大,则当前糖糖会被消灭,容易计算出剩余糖糖
对于操作二:
如果存在 iA < iB 且 A<B,对于发功会分为两种情况:
①:在iA 和iB之间发功,则A会增加,B不变
②:在iB及以后发功,则A和B都会增加,并不会影响A和B的大小比较
则,只需要计算i在i位将要消灭其前的糖糖时的大小即可用于与其前的不同组糖糖能力值进行比较即可。

#include<iostream>
#include<cstring>

using namespace std;
int a[(int)1e6+5];
int b[(int)1e6+5]={0};
int c[(int)1e6+5]={0};
int main (){
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        int s;
        for(int i=1;i<=n;i++){
            cin>>c[i]>>a[i];
        }
        int num;
        memset(b,0,sizeof(b));
        for(int i=0;i<m;i++){
            cin>>num;
            b[num+1]--;
            b[1]++;
        }
        for(int i=1;i<=n;i++)
            b[i]+=b[i-1];
        int ans0=0,ans1=0;
        for(int i=n;i>=1;i--){
          a[i]+=b[i];
            if(c[i]==0){
                if(a[i]<ans1){
                    n--;
                }
                ans0=max(ans0, a[i]);
            }
            else {
                if(a[i]<ans0)n--;
                ans1=max(ans1, a[i]);
                
            }
        }
        cout<<n<<endl;
    }
    
    return 0;
}
posted @ 2021-01-26 22:17  黒川川  阅读(91)  评论(0)    收藏  举报