题目链接:糖糖别胡说,我真的不是签到题目
题意:
分为编号为0和1两个阵营的n个人排成一列,每个人有一个能力值,在第i秒时,第i个人能消灭前面和他不同阵营并且能力值小于他的人。游戏还有buf,会有m次提高能力值的机会,在第(c[i])s,b[1]到b[c[i]]个人能力值会增加1。问最后存活人数。
题解:
这里引用官方题解
总结一下,我消灭的都是我前面的,而我前面的能力buf都已经加成完了,所以用最后能力值判断即可。倒着判断便于把两个不同阵营的最大值分别存储,小于对方阵营最大值即被消灭。
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=5e4+10;
struct Peo
{
int a,b;
}standy[N];
int c[N];
int main()
{
int t;
cin >> t;
while(t--)
{
memset(c,0,sizeof(c));
int n,m;
cin >> n >> m;
for(int i=1;i<=n;i++)
cin >> standy[i].a >> standy[i].b;
for(int i=1;i<=m;i++)
{
int tmp;
cin >> tmp;
c[tmp]++;
}
for(int i=n;i>0;i--) c[i]+=c[i+1];
for(int i=1;i<=n;i++) standy[i].b+=c[i];
int max0=0,max1=0;
int kil=0;
for(int i=n;i>=1;i--)
{
if(standy[i].a==0)
{
max0=max(max0,standy[i].b);
if(max1>standy[i].b) kil++;
}
else {
max1=max(max1,standy[i].b);
if(max0>standy[i].b) kil++;
}
}
cout << n-kil << endl;
}
}