每日一题 糖糖别胡说,我真的不是签到题目
糖糖别胡说,我真的不是签到题目
https://ac.nowcoder.com/acm/problem/14583
后缀数组写起来简单,理解也比较简单。如果在原来的基础之上发功,就算开始发功的人收益但当后续的发功结束后该来的终究会来,之前小于他的糖糖也会被灭掉,所以从后往前是可以的,还容易维护一些
#include <bits/stdc++.h> using namespace std; #define ll long long struct node { ll a,b; }m[50007]; ll c[1000007]={0};///后缀小数组 int main() { ll t; scanf("%lld",&t); while (t--) { ll n,w; memset(c,0,sizeof(c));///初始化 scanf("%lld%lld",&n,&w); for (register int i=1;i<=n;++i) { scanf("%lld%lld",&m[i].a,&m[i].b); } for (register int i=1;i<=w;++i) { int x; scanf("%d",&x); ++c[x]; } ll ans=0; ll maxn_1=-1; ll maxn_0=-1; for (register int i=n;i>=1;--i) { c[i]+=c[i+1];///累计发功量 m[i].b+=c[i];///发功 if (m[i].a){ if(maxn_1<m[i].b)///更新该组最大值 { maxn_1=m[i].b; } if (m[i].b<maxn_0)///比较后面有无其他组最大值大于他 ++ans; } else { if(maxn_0<m[i].b) maxn_0=m[i].b; if (m[i].b<maxn_1) ++ans; } } printf("%lld\n",n-ans);///所有减去死亡的 正难则反 } return 0; }