QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#580871 | #6837. AC Automaton | cyj888 | WA | 11ms | 30776kb | C++14 | 4.3kb | 2024-09-22 00:32:02 | 2024-09-22 00:32:09 |
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];//belong
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 ;
}
int find (int u) {
return bl[u] = (bl[fa[u][0]] ? u : find (fa[u][0]));
}
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 now = fa[t[i]][0];
if (!bl[now]) t[++ t[0]] = find (now);
}
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]] > 0) b[t[i]].clear (), oth[t[i]] = 0;
}
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;
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 28804kb
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: 11ms
memory: 30776kb
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:
2342 2342 2345 2340 2760 2768 2767 2772 2772 2772 2772 2772 2772 2772 2767 2767 2767 2764 2766 2766 2766 2765 2761 2764 2764 2772 2772 2772 2772 2772 2772 2772 2777 2777 2777 2779 2771 2774 2774 2783 2775 2772 2772 2768 2769 2772 2772 2769 2774 2774 2774 2777 2781 2779 2779 2779 2783 2787 2782 2788 ...
result:
wrong answer 1st lines differ - expected: '2344', found: '2342'