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

先考虑没有娇姐发功怎么做。

考虑每只糖糖最后能不能存活:第\(i\)只糖糖能存活的条件是他后面没有比他大的另外一组的糖糖,所以我们只需要从后往前扫描维护当前位置往后每一组糖糖的最大值是多少然后和当前糖糖的能力值比较就行。

现在再来考虑娇姐发功的问题。
娇姐会在第\(c_i\)秒使得前\(c_i\)个人的能力值+1,其实不影响第\(c_i\)个糖糖在第\(c_i\)秒消灭他前面的糖糖(大家都加一,大小关系不变);但是会影响后面的糖糖打它。可以用离线做法, 先让娇姐发完所有的功。

于是,我们先得出每个糖糖最后的能力值,再从后往前判断他是否还存活。

其中,维护每个糖糖最后的能力值可以用差分来维护。

const int N=50010;
PII a[N];
int b[N];  // 差分数组
int n,m;
 
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n >> m;
 
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &a[i].fi, &a[i].se);
            b[i] = a[i].se - a[i-1].se;
        }
 
        for (int i = 1; i <= m; i++)
        {
            int t;
            scanf("%d", &t);
            b[1]++;
            b[t+1]--;
        }
 
        for (int i = 1; i <= n; i++)
        {
            b[i] += b[i-1];
            a[i].se = b[i];
        }
 
        int max0 = 0,max1 = 0;
        int ans = n;
        for (int i = n; i; i--)
        {
            if (a[i].fi == 0)
            {
                if (max1 > a[i].se) ans--;
                max0 = max(max0, a[i].se);
            }
            else
            {
                if (max0 > a[i].se) ans--;
                max1 = max(max1, a[i].se);
            }
        }
 
        cout << ans << endl;
    }
    //system("pause");
    return 0;
}
posted @ 2021-05-15 16:46  Dazzling!  阅读(21)  评论(0编辑  收藏  举报