QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#581210#6837. AC Automatoncyj888TL 309ms30156kbC++144.4kb2024-09-22 10:43:322024-09-22 10:43:32

Judging History

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

  • [2024-09-22 10:43:32]
  • 评测
  • 测评结果:TL
  • 用时:309ms
  • 内存:30156kb
  • [2024-09-22 10:43:32]
  • 提交

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;
	ott (i, 1, n) t[++ t[0]] = i; 
    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];
    	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]] == t[i]) 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;
	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;
}
/*
10 5
??????????
1 1 2 2 3 3 4 4 5
1 ?
1 ?
1 ?
1 ?
1 ?


*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 30156kb

input:

5 3
AC??C
1 2 2 1
1 ?
4 A
2 ?

output:

4
3
3

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 309ms
memory: 28912kb

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
2768
2768
2772
2772
2772
2772
2772
2772
2772
2767
2767
2767
2767
2764
2766
2766
2769
2765
2761
2764
2767
2772
2772
2772
2772
2772
2772
2777
2777
2777
2777
2774
2771
2774
2782
2778
2778
2772
2768
2772
2772
2772
2772
2772
2774
2774
2778
2781
2781
2779
2782
2784
2787
2782
2786
2788
...

result:

ok 1000 lines

Test #3:

score: -100
Time Limit Exceeded

input:

300000 300000
AAA?CA?AA?AC?A?CCA?AACCAAA???CA?ACCAACCCCAACAAA?CCAAAC?A?C??CC?C?C?CCCA?CAA?ACA??C?C?AC??CA??ACA?AA???CACAAA?CACCCCCCC?A?AAAAAC?AACCA????CCC?C?AAACCCAA?C???CCCC?AAACAAA???A?CAAC??A??A??CCCC??AA?C??ACA?AACAAA????CAA???AAAAACC?C?CCA?CCAA?AAC?CC?CA?A??CC??CCAC??C??????AAC?AA?AA?AAC?C??AAC...

output:


result: