QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#580806 | #6837. AC Automaton | cyj888 | WA | 16ms | 33316kb | C++14 | 4.2kb | 2024-09-22 00:00:44 | 2024-09-22 00:00:44 |
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];//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 (!oth) oth = v, t[++ t[0]] = v;
fuck (v, oth);
}
}
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, m) t[++ t[0]] = lca (t[i - 1], t[i]); t[++ 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 z = fa[t[i]][0], now = z;
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) {
assert (bl[i]);
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]] = 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;
if (bl[t[i]] == t[i]) b[t[i]].clear ();
}
ott (i, 1, n) bl[i] = 0, E[i].clear ();
t[0] = 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 = 1; //ott (i, 1, n) b[i].clear ();
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;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 29348kb
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
Wrong Answer
time: 16ms
memory: 33316kb
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...
output:
2344 2344 2343 2341 2760 2768 2771 2772 2772 2772 2772 2772 2772 2768 2767 2767 2767 2765 2765 2766 2768 2766 2762 2763 2766 2772 2772 2772 2772 2772 2772 2776 2777 2777 2777 2775 2772 2773 2781 2779 2778 2773 2769 2771 2772 2772 2772 2771 2773 2774 2777 2780 2781 2780 2781 2783 2786 2783 2785 2787 ...
result:
wrong answer 2nd lines differ - expected: '2345', found: '2344'