QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#583403 | #6837. AC Automaton | cyj888 | RE | 0ms | 28872kb | C++11 | 4.4kb | 2024-09-22 19:50:08 | 2024-09-22 19:50:08 |
Judging History
answer
#include <bits/stdc++.h>
#define pb push_back
#define ott(i,l,r) for (int i = l; i <= r; i ++)
#define tto(i,l,r) for (int i = r; i >= l; i --)
using namespace std;
using ll = long long;
int read () {
int x = 0; bool f = 0; char c = getchar ();
while (!isdigit (c)) f |= (c == '-'), c = getchar ();
while (isdigit (c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar ();
if (f) x = -x; return x;
}
const int N = 3e5 + 110;
int n, m, q, idx, B, res;
vector <int> e[N], E[N];
int up[N], dn[N];
int fa[N][20], dfn[N], dep[N];
char s[N];
void dfs0 (int u) {
dfn[u] = ++ idx, dep[u] = dep[fa[u][0]] + 1;
ott (j, 1, 18) fa[u][j] = fa[fa[u][j - 1]][j - 1];
for (int v : e[u]) dfs0 (v);
return ;
}
int lca (int x, int y) {
if (dep[x] < dep[y]) swap (x, y);
tto (j, 0, 18) if (dep[fa[x][j]] >= dep[y]) x = fa[x][j];
if (x == y) return x;
tto (j, 0, 18) if (fa[x][j] != fa[y][j]) x = fa[x][j], y = fa[y][j];
return fa[x][0];
}
struct OPT {
int x; char c;
} a[N];
struct BLOCK {
int ac, now, sum;//ac = 'A'count
int s[1100];
void ins (int v) {
if (v >= now) ++ sum;
if (-m <= v && v <= m) ++ s[v + m];
return ;
}
void add (int v) {
if (v == 1) {
sum -= s[(now ++) + m];
res -= sum;
}
if (v == -1) {
res += sum;
sum += s[(-- now) + m];
}
return ;
}
void clear () {
ac = now = sum = 0;
ott (i, 0, m + m) s[i] = 0;
return ;
}
} b[N];
int t[N], FA[N], bl[N], oth[N];//bl = belong & below
bool cmp (int x, int y) {
return dfn[x] < dfn[y];
}
void fuck (int u, int z) {
bl[u] = z;
for (int v : e[u]) fuck (v, z);
return ;
}
void cpr (int u) {
int OTH = 0;
for (int v : e[u]) {
if (bl[v]) cpr (v);
else if (bl[u] < 0) {
if (!OTH) OTH = t[++ t[0]] = v;
fuck (v, OTH);
}
else {
if (!oth[bl[u]]) oth[bl[u]] = t[++ t[0]] = v;
fuck (v, oth[bl[u]]);
}
}
return ;
}
void red (int u) {
dn[u] = 0;
for (int v : e[u]) {
up[v] = up[u] + (s[u] != 'C');
red (v);
dn[u] += dn[v] + (s[v] != 'A');
}
if (s[u] == 'A') res += dn[u];
if (s[u] == '?') res += max (0, dn[u] - up[u]);
return ;
}
void cup (int u, int val) {
for (int v : E[u]) {
if (bl[v] < 0) {
if (s[v] == '?') res -= max (0, dn[v] - up[v]);
up[v] += val;
if (s[v] == '?') res += max (0, dn[v] - up[v]);
}
else {
b[v].add (val);
}
cup (v, val);
}
return ;
}
void cdn (int u, int val) {
if (!u) return ;
if (bl[u] < 0) {
if (s[u] == '?') res -= max (0, dn[u] - up[u]);
dn[u] += val; if (s[u] == 'A') res += val;
if (s[u] == '?') res += max (0, dn[u] - up[u]);
}
else {
b[u].add (-val), res += b[u].ac * val;
}
cdn (FA[u], val);
return ;
}
void sol () {
ott (i, 1, m) t[++ t[0]] = a[i].x;
sort (t + 1, t + 1 + t[0]), t[0] = unique (t + 1, t + 1 + t[0]) - t - 1;
sort (t + 1, t + 1 + t[0], cmp);
ott (i, 2, t[0]) t[t[0] + i - 1] = lca (t[i - 1], t[i]); t[t[0] += t[0]] = 1;
sort (t + 1, t + 1 + t[0]), t[0] = unique (t + 1, t + 1 + t[0]) - t - 1;
ott (i, 1, t[0]) bl[t[i]] = -t[i];//区分会修改的点
ott (i, 2, t[0]) {
int now = fa[t[i]][0], z = now;
if (!bl[now]) {
t[++ t[0]] = z;
while (!bl[now]) {
bl[now] = z;
now = fa[now][0];
}
}
}
cpr (1), sort (t + 1, t + 1 + t[0], cmp);
ott (i, 1, n) {
if (bl[i] < 0) continue;
if (s[i] == 'A') ++ b[bl[i]].ac;
if (s[i] == '?') b[bl[i]].ins (dn[i] - up[i]);
}
ott (i, 2, t[0]) E[FA[t[i]] = abs (bl[lca (t[i - 1], t[i])])].pb (t[i]);
ott (i, 1, m) {
int x = a[i].x; char c = a[i].c;
if (s[x] != 'C') cup (x, -1); if (s[x] != 'A') cdn (FA[x], -1);
if (s[x] == 'A') res -= dn[x];
if (s[x] == '?') res -= max (0, dn[x] - up[x]);
s[x] = c;
if (s[x] == 'A') res += dn[x];
if (s[x] == '?') res += max (0, dn[x] - up[x]);
if (s[x] != 'C') cup (x, 1); if (s[x] != 'A') cdn (FA[x], 1);
printf ("%d\n", res);
}
ott (i, 1, t[0]) {
FA[t[i]] = 0, E[t[i]].clear ();
if (bl[t[i]] == t[i]) b[t[i]].clear (), oth[t[i]] = 0;
t[i] = 0;
}
ott (i, 1, n) bl[i] = 0;
t[0] = m = 0, res = 0;
return ;
}
int main () {
n = read (), q = read (), cin >> s + 1; ott (i, 2, n) e[fa[i][0] = read ()].pb (i);
B = (int)sqrt (q);
dfs0 (1), red (1); ott (i, 1, q) {
int x = read (); char c = getchar ();
a[++ m] = {x, c};
if (i % B == 0 || i == q) {
sol (), red (1);
}
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 28872kb
input:
5 3 AC??C 1 2 2 1 1 ? 4 A 2 ?
output:
4 3 3
result:
ok 3 lines
Test #2:
score: -100
Runtime Error
input:
1000 1000 AC?ACCCCC?CCA??CCCCC?A?AC?C??C?ACCCACC?C?CCC?CACACA???????C?????CC?C?AAAAACCA??AAAACACACA???AACAC?CCC?CAC?AAAACCAC???ACAA??A??A?CA?A?ACACACCAA?ACACA?AC??AC??ACAAACCC??CAA?A???CC?AA??AC???A?CCCC??CACCAACC?AA?C?AAACCCA?AAA??C?CC??CACCACAACCA?AACCC?A?CCC?CC???AA?CACCCAAC??CAA??C?AA??CA???CAAA...