纯正的模拟题,但是蒟蒻主包写的时候因为一些小bug调了好久,半夜有点红温
本题的核心是用map去存储对方牌河中牌的数量,以及分op=1和op=2两种情况分别进行分析
另外我们要开一个数组去记录每张牌是否是安全牌状态
当op=1时,因为增加了一张数值为num的牌(mp[n]++),所以数值为n-3和n+3的牌就可能变为安全牌(前提是这两个牌在1-m的范围内,也就是合法),导致答案增加,另外,如果他们本来就是安全牌,则答案不会变动
当op=2时,减少了一张数值为num的牌(mp[n]--),所以数值为n - 3与n + 3的牌可能不再安全(前提依旧是它们合法),导致答案减少。
如果减少了一张以后,数值为num的牌仍然有大于等于1张,说明这次减少实质上产生不了任何影响
否则减少一张以后,数值为num的牌正好清空,那我们要分别判断数值为n -6和n+6的牌是否合法,如果他们不合法,那么答案是否减少只取决于数值为num的牌,否则还要考虑num-6与num+6的牌有没有在牌河里
思路大概就是这样,结合代码和注释食用就行了,应该写的还是挺清楚的
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << '\n';
// #define int long long
#define ctz __builtin_ctzll // 返回二进制表示中末尾连续0的个数
#define clz __builtin_clzll // 返回二进驻表示中先导0的个数
#define count1 __builtin_popcountll // 返回二进制表示中1的个数
// 上面仨不是ll的时候记得调整
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 lll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10;
const double EPS = 1e-6;
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll dir[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
ll dirr[8][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}, {1, 1}, {1, -1}, {-1, -1}, {-1, 1}};
void LiangBaiKai()
{
}
void Aiden()
{
ll m, n, k, sum = 0, ans = 0, num = 0, mi = INF, ma = -INF, cnt = 0, x, y, z, len, t, l, r, cur;
string s1, s2;
ll q;
cin >> m >> q;
vector<ll> a(m + 1); // a数组用来存储m张牌是否安全的状态
map<ll, ll> mp; // mp用来存储这m张牌在牌河里的张数情况
while (q--)
{
ll op;
cin >> op >> n; // 输入操作以及num
if (op == 1)
{
mp[n]++; // 多摸了一张自然对应数量增加
if (n - 3 >= 1 && !a[n - 3]) // 当n-3这个数值的牌合法而且它不是安全牌时,它会变为安全牌,同时答案+1
{
a[n - 3] = 1;
ans++;
}
if (n + 3 <= m && !a[n + 3]) // 当n+3这个数值的牌合法而且它不是安全牌时,它会变为安全牌,同时答案+1
{
a[n + 3] = 1;
ans++;
}
}
else
{
mp[n]--; // 丢掉了一张自然对应数量减少
if (mp[n]) // 如果丢掉了一张以后还有多的,那啥影响也没有,直接输出答案并且跳过这次问询
{
cout << ans << endl;
continue;
}
if (n - 3 >= 1) // 如果n-3数值的这张牌合法
{
bool flag = 0;
if (n - 6 >= 1 && mp[n - 6] > 0) // 如果n-6这张牌合法,那么检查他在牌河里是否存在
flag = 1;
if (!flag && a[n - 3]) // n-6的牌与n的牌在牌河里都不存在,那么如果n-3的牌本来是安全牌,现在就不再安全了,同时答案-1
{
a[n - 3] = 0;
ans--;
}
}
if (n + 3 <= m) // 如果n+3数值的这张牌合法
{
bool flag = 0;
if (n + 6 <= m && mp[n + 6] > 0) // 如果n+6这张牌合法,那么检查他在牌河里是否存在
flag = 1;
if (!flag && a[n + 3]) // n+6的牌与n的牌在牌河里都不存在,那么如果n+3的牌本来是安全牌,现在就不再安全了,同时答案-1
{
a[n + 3] = 0;
ans--;
}
}
}
cout << ans << endl;
}
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
LiangBaiKai();
int _ = 1;
// cin >> _;
while (_--)
Aiden();
return 0;
}

京公网安备 11010502036488号