QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#583403#6837. AC Automatoncyj888RE 0ms28872kbC++114.4kb2024-09-22 19:50:082024-09-22 19:50:08

Judging History

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

  • [2024-09-22 19:50:08]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:28872kb
  • [2024-09-22 19:50:08]
  • 提交

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...

output:


result: