QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#580806#6837. AC Automatoncyj888WA 16ms33316kbC++144.2kb2024-09-22 00:00:442024-09-22 00:00:44

Judging History

你现在查看的是最新测评结果

  • [2024-09-22 00:00:44]
  • 评测
  • 测评结果:WA
  • 用时:16ms
  • 内存:33316kb
  • [2024-09-22 00:00:44]
  • 提交

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'