纯正的模拟题,但是蒟蒻主包写的时候因为一些小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;
}