QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#588426 | #6837. AC Automaton | cyj888 | RE | 0ms | 0kb | C++11 | 5.8kb | 2024-09-25 11:00:11 | 2024-09-25 11:42:41 |
answer
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ott(i,l,r) for (register int i = l; i <= r; ++ i)
#define read(x) {x = 0; char c; while ((c = getchar ()) < 48); do x = (x << 3) + (x << 1) + (c ^ 48); while ((c = getchar ()) > 47);}
#define print() {long long x = res; len = 0; if (!x) putchar (48); while (x) pc[++ len] = x % 10, x /= 10; while (len) putchar (pc[len --] + 48); putchar ('\n');}
#define cdn1(ttu) {int tu, u = ttu; while (u) {if (u <= LIM) {tu = val[u]; if (!(ch[tu] ^ '?')) res -= Max (dn[tu] - up[tu]); ++ dn[tu]; if (ch[tu] == 'A') ++ res; if (!(ch[tu] ^ '?')) res += Max (dn[tu] - up[tu]);} else b[u - LIM].add (-1), res += b[u - LIM].ac; u = FA[u];}}
#define cdn2(ttu) {int tu, u = ttu; while (u) {if (u <= LIM) {tu = val[u]; if (!(ch[tu] ^ '?')) res -= Max (dn[tu] - up[tu]); -- dn[tu]; if (ch[tu] == 'A') -- res; if (!(ch[tu] ^ '?')) res += Max (dn[tu] - up[tu]);} else b[u - LIM].add (1), res -= b[u - LIM].ac; u = FA[u];}}
using namespace std;
const int N = 3e5 + 110, B = 900, inf = 0x3f3f3f3f;
int n, m, q, idx, len, Z, OTH, LIM;
long long res;
char pc[65];
vector <int> e[N], E[B << 2];
int up[N], dn[N], dfn[N], dep[N], fa[N], lg[N << 1], f[N << 1][20];
char ch[N];
void dfs0 (int u) {
f[dfn[u] = ++ idx][0] = u, dep[u] = dep[fa[u]] + 1;
for (int v : e[u]) {
dfs0 (v);
f[++ idx][0] = u;
}
return ;
}
inline int lca (int x, int y) {
x = dfn[x], y = dfn[y];
if (x > y) swap (x, y);
Z = lg[y - x + 1], x = f[x][Z], y = f[y - (1 << Z) + 1][Z];
return dep[x] < dep[y] ? x : y;
}
struct OPT {
int x; char c;
} a[B + 1];
struct BLOCK {
int ac, now, val, sum;//ac = 'A'count
vector <int> s; vector <pair <int, int> > t;
inline void upd (int i) {
if (!(ch[i] ^ 'A')) ++ ac;
if (!(ch[i] ^ '?')) {
i = dn[i] - up[i];
if (i >= 0) ++ sum;
if (-m <= i && i <= m) s.emplace_back (i);
}
return ;
}
inline void init () {
t.emplace_back (-inf, 0);
if (s.size ()) {
sort (s.begin (), s.end ());
ott (i, 0, s.size () - 1) {
int cnt = 1; while (i + 1 < s.size () && !(s[i] ^ s[i + 1])) ++ i, ++ cnt;
t.emplace_back (s[i], cnt);
}
}
t.emplace_back (inf, 0);
int l = 0, r = t.size () - 1, mid;
while (l <= r) {
mid = l + r >> 1;
if (t[mid].fi >= 0) now = mid, r = mid - 1;
else l = mid + 1;
}
return ;
}
inline void add (int v) {
if (!(v ^ 1)) {
if (!(t[now].fi ^ val ++)) sum -= t[now ++].se;
res -= sum;
}
if (!(v ^ -1)) {
res += sum;
if (!(t[now - 1].fi ^ -- val)) sum += t[-- now].se;
}
return ;
}
inline void clear () {
ac = now = val = sum = 0, vector <int> ().swap (s), vector <pair <int, int> > ().swap (t);
return ;
}
} b[B << 1 | 1];
int id[N], val[B << 2], FA[B << 2];
inline int Max (const int &x) {
return x > 0 ? x : 0;
}
inline bool cmp (const int &x, const int &y) {
return dfn[x] < dfn[y];
}
void push (int u, int z) {
b[z].upd (u);
for (int v : e[u]) push (v, z);
return ;
}
void find (int x) {
if (id[fa[x]]) {
val[Z = id[x] = ++ idx] = x, Z -= LIM;
return ;
}
find (fa[x]), b[Z].upd (fa[x]);
for (int v : e[fa[x]]) {
if (!(v ^ x)) continue;
if (!OTH) val[OTH = id[v] = ++ idx] = v, OTH -= LIM;
push (v, OTH);
}
return ;
}
void red (int u) {
dn[u] = 0;
for (int v : e[u]) {
up[v] = up[u]; if (ch[u] ^ 'C') ++ up[v];
red (v);
dn[u] += dn[v]; if (ch[v] ^ 'A') ++ dn[u];
}
if (!(ch[u] ^ 'A')) res += dn[u];
if (!(ch[u] ^ '?')) res += Max (dn[u] - up[u]);
return ;
}
void cup (int u, int V) {
for (int v : E[u]) {
if (v <= LIM) {
int tv = val[v];
if (!(ch[tv] ^ '?')) res -= Max (dn[tv] - up[tv]);
up[tv] += V;
if (!(ch[tv] ^ '?')) res += Max (dn[tv] - up[tv]);
}
else b[v - LIM].add (V);
cup (v, V);
}
return ;
}
void sol () {
ott (i, 1, m) val[++ idx] = a[i].x;
sort (val + 1, val + 1 + idx), idx = unique (val + 1, val + 1 + idx) - val - 1;
sort (val + 1, val + 1 + idx, cmp);
ott (i, 2, idx) val[idx + i - 1] = lca (val[i - 1], val[i]); val[idx += idx] = 1;
sort (val + 1, val + 1 + idx), idx = unique (val + 1, val + 1 + idx) - val - 1;
ott (i, 1, idx) id[val[i]] = i;
LIM = idx;
ott (i, 2, LIM) {
if (!id[fa[val[i]]]) {
OTH = Z = 0, find (val[i]), Z += LIM;
if (OTH) OTH += LIM, E[FA[OTH] = i].pb (OTH);
E[FA[Z] = id[fa[val[Z]]]].pb (Z), E[FA[i] = Z].pb (i);
}
else E[FA[i] = id[fa[val[i]]]].pb (i);
}
ott (i, 1, LIM) {
OTH = 0; for (int v : e[val[i]]) {
if (id[v]) continue;
if (!OTH) {
val[OTH = id[v] = ++ idx] = v;
E[FA[OTH] = i].pb (OTH);
OTH -= LIM;
}
push (v, OTH);
}
}
Z = idx - LIM; ott (i, 1, Z) b[i].init ();
ott (i, 1, m) {
int x = a[i].x; char c = a[i].c;
if (ch[x] ^ 'C') cup (id[x], -1); if (ch[x] ^ 'A') cdn2 (FA[id[x]]);
if (!(ch[x] ^ 'A')) res -= dn[x];
if (!(ch[x] ^ '?')) res -= Max (dn[x] - up[x]);
ch[x] = c;
if (!(ch[x] ^ 'A')) res += dn[x];
if (!(ch[x] ^ '?')) res += Max (dn[x] - up[x]);
if (ch[x] ^ 'C') cup (id[x], 1); if (ch[x] ^ 'A') cdn1 (FA[id[x]]);
print ();
}
ott (i, 1, idx) {
E[i].clear (), FA[i] = 0;
id[val[i]] = 0, val[i] = 0;
}
Z = idx - LIM; ott (i, 1, Z) b[i].clear ();
m = idx = 0, res = 0, red (1);
return ;
}
int main () {
freopen ("data.in", "r", stdin); freopen ("res.out", "w", stdout);
read (n); read (q); ott (i, 1, n) ch[i] = getchar (); ott (i, 2, n) {
read (fa[i]);
e[fa[i]].pb (i);
}
dfs0 (1), red (1);
ott (j, 1, 19) {
ott (i, 1, idx - (1 << j) + 1) {
OTH = f[i][j - 1], LIM = f[i + (1 << j - 1)][j - 1];
f[i][j] = dep[OTH] < dep[LIM] ? OTH : LIM;
}
}
lg[0] = -1; ott (i, 1, idx) lg[i] = lg[i >> 1] + 1;
idx = 0; ott (i, 1, q) {
int x; read (x); char c = getchar ();
a[++ m] = {x, c};
if (i % B == 0 || i == q) sol ();
}
return 0;
}
詳細信息
Test #1:
score: 0
Dangerous Syscalls
input:
5 3 AC??C 1 2 2 1 1 ? 4 A 2 ?