QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#580801#6837. AC Automatoncyj888WA 5ms29900kbC++144.2kb2024-09-21 23:59:452024-09-21 23:59:46

Judging History

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

  • [2024-09-21 23:59:46]
  • 评测
  • 测评结果:WA
  • 用时:5ms
  • 内存:29900kb
  • [2024-09-21 23:59:45]
  • 提交

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 = (int)sqrt (q); //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: 3ms
memory: 27960kb

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: 5ms
memory: 29900kb

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
2345
2342
2342
2777
2777
2778
2778
2778
2778
2778
2778
2778
2776
2776
2776
2776
2773
2775
2775
2776
2772
2770
2771
2774
2779
2779
2779
2779
2779
2779
2777
2777
2777
2777
2777
2774
2775
2783
2779
2779
2775
2771
2773
2773
2773
2773
2773
2775
2775
2779
2782
2782
2782
2785
2787
2790
2788
2788
2788
...

result:

wrong answer 5th lines differ - expected: '2768', found: '2777'