MLE or TLE on 4,但不知道怎么优化。
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
inline int read()
{
int s = 0, w = 1;
char c = getchar();
for ( ; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for ( ; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
const int N = 1e6 + 10;
bool Mbe;
int n, q;
struct Node
{
int l, r;
} tr[N * 21];
gp_hash_table<int, bool> T;
int w[N];
int root[N], idx;
int back[N];
int lop[N], lv[N], top, i;
bool Med;
int build(int l, int r)
{
int p = ++ idx;
if (l == r) return p;
int mid = l + r >> 1;
tr[p].l = build(l, mid), tr[p].r = build(mid + 1, r);
return p;
}
int add(int p, int l, int r, int x, int v)
{
int q = ++ idx; tr[q] = tr[p];
if (l == r)
{
T[q] = T[p];
if (v == 1 && T[q] == 0) w[i] ++ ;
if (v == -1 && T[q] == 1) w[i] -- ;
T[q] += v; return q;
}
int mid = l + r >> 1;
if (x <= mid) tr[q].l = add(tr[p].l, l, mid, x, v);
else tr[q].r = add(tr[p].r, mid + 1, r, x, v);
return q;
}
int main()
{
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
fprintf(stderr, "%.3lf MB\n", (&Mbe - &Med) / 1048576.0);
root[0] = build(1, N - 1);
scanf("%d", &q); int len;
for (i = 1, len = 0; i <= q; i ++ )
{
char op[2]; scanf("%s", op);
if (*op == '+')
{
int x; scanf("%d", &x);
w[i] = w[i - 1]; root[i] = add(root[i - 1], 1, N - 1, x, 1); len ++ ;
back[len] = i; lop[ ++ top] = 1; lv[top] = x;
}
else if (*op == '-')
{
int k; scanf("%d", &k);
len -= k; root[i] = root[back[len]]; w[i] = w[back[len]];
back[len] = i; lop[ ++ top] = 2; lv[top] = k;
}
else if (*op == '!')
{
if (lop[top] == 1)
{
w[i] = w[i - 1]; root[i] = add(root[i - 1], 1, N - 1, lv[top], -1);
len -- ; back[len] = i;
}
else
{
len += lv[top]; root[i] = root[back[len]]; w[i] = w[back[len]];
back[len] = i;
}
top -- ;
}
else
{
root[i] = root[i - 1]; w[i] = w[i - 1];
printf("%d\n", w[i]);
}
}
return 0;
}