QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#590103#6837. AC Automatoncyj888TL 0ms21316kbC++116.2kb2024-09-25 21:36:352024-09-25 21:36:35

Judging History

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

  • [2024-09-25 21:36:35]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:21316kb
  • [2024-09-25 21:36:35]
  • 提交

answer

#include <bits/stdc++.h>
#define ott(i,l,r) for (register int i = l; i <= r; ++ i)
#define read(x) {x = 0; char c; while ((c = getchar ()) < 48); do x = (x << 3) + (x << 1) + (c ^ 48); while ((c = getchar ()) > 47);}
#define print() {long long x = res; len = 0; if (!x) putchar (48); while (x) pc[++ len] = x % 10, x /= 10; while (len) putchar (pc[len --] + 48); putchar ('\n');}
#define cdn1(ttu) {int tu, u = ttu; while (u) {if (u <= LIM) {tu = val[u]; if (!(ch[tu] ^ '?')) res -= Max (dn[tu] - up[tu]); ++ dn[tu]; if (ch[tu] == 'A') ++ res; if (!(ch[tu] ^ '?')) res += Max (dn[tu] - up[tu]);} else b[u - LIM].add2 (), res += b[u - LIM].ac; u = FA[u];}}
#define cdn2(ttu) {int tu, u = ttu; while (u) {if (u <= LIM) {tu = val[u]; if (!(ch[tu] ^ '?')) res -= Max (dn[tu] - up[tu]); -- dn[tu]; if (ch[tu] == 'A') -- res; if (!(ch[tu] ^ '?')) res += Max (dn[tu] - up[tu]);} else b[u - LIM].add1 (), res -= b[u - LIM].ac; u = FA[u];}}
using namespace std;
const int N = 3e5 + 110, B = 1000, inf = 0x3f3f3f3f;
int n, m, q, idx, len, Z, OTH, LIM;
long long res; char pc[65];
vector <int> e[N], E[B << 2];
int up[N], dn[N], dfn[N], dep[N], fa[N], lg[N << 1], f[N << 1][20];
char ch[N];
void dfs0 (int u) {
	f[dfn[u] = ++ idx][0] = u, dep[u] = dep[fa[u]] + 1;
	for (int v : e[u]) {
		dfs0 (v);
		f[++ idx][0] = u;
	}
	return ;
}
inline int lca (int x, int y) {
	x = dfn[x], y = dfn[y]; if (x > y) swap (x, y);
	Z = lg[y - x + 1]; x = f[x][Z], y = f[y - (1 << Z) + 1][Z];
	return dep[x] < dep[y] ? x : y;
}
struct OPT {
	int x; char c;
} a[B + 1];
struct BLOCK {
	int ac, now, val, sum;//ac = 'A'count
	vector <int> s; vector <pair <int, int> > t;
	inline void upd (int i) {
		if (!(ch[i] ^ 'A')) ++ ac;
		if (!(ch[i] ^ '?')) {
			i = dn[i] - up[i]; if (i >= 0) ++ sum;
			if (-m <= i && i <= m) s.emplace_back (i);
		}
		return ;
	}
	inline void init () {
		t.emplace_back (-inf, 0);
		if (s.size ()) {
			sort (s.begin (), s.end ());
			ott (i, 0, s.size () - 1) {
	        	int cnt = 1; while (i + 1 < s.size () && !(s[i] ^ s[i + 1])) ++ i, ++ cnt;
	        	t.emplace_back (s[i], cnt);
			}
		}
		t.emplace_back (inf, 0);
		int l = 0, r = t.size () - 1, mid;
		while (l <= r) {
			mid = l + r >> 1;
			if (t[mid].first >= 0) now = mid, r = mid - 1;
			else l = mid + 1;
		}
		return ;
	}
	inline void add1 () {
		if (!(t[now].first ^ val ++)) sum -= t[now ++].second; res -= 1ll * sum;
		return ;
	}
	inline void add2 () {
		res += 1ll * sum; if (!(t[now - 1].first ^ -- val)) sum += t[-- now].second;
		return ;
	}
	inline void clear () {
		ac = now = val = sum = 0, vector <int> ().swap (s), vector <pair <int, int> > ().swap (t);
		return ;
	}
} b[B << 1 | 1];
int id[N], val[B << 2], FA[B << 2];
inline int Max (const int &x) {
	return x > 0 ? x : 0;
}
inline bool cmp (const int &x, const int &y) {
	return dfn[x] < dfn[y];
}
inline void push (int u) {
	b[OTH].upd (u); for (int v : e[u]) push (v); 
	return ;
}
inline void find (int x) {
	if (id[fa[x]]) {
		val[Z = id[x] = ++ idx] = x; Z -= LIM;
		return ;
	}
	find (fa[x]); b[Z].upd (fa[x]);
	for (int v : e[fa[x]]) {
		if (!(v ^ x)) continue;
		if (!OTH) val[OTH = id[v] = ++ idx] = v; OTH -= LIM;
		push (v);
	}
	return ;
} 
inline void red (int u) {
	dn[u] = 0;
	for (int v : e[u]) {
		up[v] = up[u]; if (ch[u] ^ 'C') ++ up[v];
		red (v);
		dn[u] += dn[v]; if (ch[v] ^ 'A') ++ dn[u];
	}
	if (!(ch[u] ^ 'A')) res += 1ll * dn[u];
	if (!(ch[u] ^ '?')) res += 1ll * Max (dn[u] - up[u]);
	return ;
}
inline void cup1 (int u) {
	for (int v : E[u]) {
		if (v <= LIM) {
			int tv = val[v];
			if (!(ch[tv] ^ '?')) res -= 1ll * Max (dn[tv] - up[tv]);
			++ up[tv];
			if (!(ch[tv] ^ '?')) res += 1ll * Max (dn[tv] - up[tv]);
		}
		else b[v - LIM].add1 ();
		cup1 (v);
	}
	return ;
}
inline void cup2 (int u) {
	for (int v : E[u]) {
		if (v <= LIM) {
			int tv = val[v];
			if (!(ch[tv] ^ '?')) res -= 1ll * Max (dn[tv] - up[tv]);
			-- up[tv];
			if (!(ch[tv] ^ '?')) res += 1ll * Max (dn[tv] - up[tv]);
		}
		else b[v - LIM].add2 ();
		cup2 (v);
	}
	return ;
}
inline void sol () {
    ott (i, 1, m) val[i] = a[i].x; 
	idx = m; sort (val + 1, val + 1 + idx), idx = unique (val + 1, val + 1 + idx) - val - 1; sort (val + 1, val + 1 + idx, cmp);
    ott (i, 2, idx) val[idx + i - 1] = lca (val[i - 1], val[i]); 
	val[idx += idx] = 1; sort (val + 1, val + 1 + idx), idx = unique (val + 1, val + 1 + idx) - val - 1;
    ott (i, 1, idx) id[val[i]] = i; LIM = idx;
    ott (i, 2, LIM) {
    	if (!id[fa[val[i]]]) {
    		OTH = 0, find (val[i]);
    		if (OTH) {
    			OTH += LIM;
				E[FA[OTH] = i].emplace_back (OTH);
			}
    		Z += LIM; E[FA[Z] = id[fa[val[Z]]]].emplace_back (Z), E[FA[i] = Z].emplace_back (i);
		}
		else E[FA[i] = id[fa[val[i]]]].emplace_back (i);
	}
	ott (i, 1, LIM) {
		OTH = 0; for (int v : e[val[i]]) {
			if (id[v]) continue;
			if (!OTH) {
				val[OTH = id[v] = ++ idx] = v;
				E[FA[OTH] = i].emplace_back (OTH); OTH -= LIM;
			}
			push (v);
		}
	}
	Z = idx - LIM; ott (i, 1, Z) b[i].init ();
	ott (i, 1, m) {
		int x = a[i].x; char c = a[i].c;
		if (ch[x] ^ 'C') cup2 (id[x]); if (ch[x] ^ 'A') cdn2 (FA[id[x]]);
		if (!(ch[x] ^ 'A')) res -= 1ll * dn[x];
		if (!(ch[x] ^ '?')) res -= 1ll * Max (dn[x] - up[x]);
		ch[x] = c;
		if (!(ch[x] ^ 'A')) res += 1ll * dn[x];
		if (!(ch[x] ^ '?')) res += 1ll * Max (dn[x] - up[x]);
		if (ch[x] ^ 'C') cup1 (id[x]); if (ch[x] ^ 'A') cdn1 (FA[id[x]]);
		print ();
	}
	ott (i, 1, idx) {
		E[i].clear (), FA[i] = 0, id[val[i]] = 0;
		val[i] = 0;
	}
	Z = idx - LIM; m = idx = 0, res = 0, red (1); ott (i, 1, Z) b[i].clear ();
	return ;
}
int main () {
	//freopen ("data.in", "r", stdin); freopen ("res.out", "w", stdout);
	read (n); read (q); scanf ("%s", ch + 1); ott (i, 2, n) {
		read (fa[i]); e[fa[i]].emplace_back (i);
	}
	dfs0 (1), red (1);
	ott (j, 1, 19) {
		ott (i, 1, idx - (1 << j) + 1) {
			OTH = f[i][j - 1], LIM = f[i + (1 << j - 1)][j - 1];
			f[i][j] = dep[OTH] < dep[LIM] ? OTH : LIM;
		}
	}
	lg[0] = -1;	ott (i, 1, idx) lg[i] = lg[i >> 1] + 1; idx = 0;
	int x; char c;
	ott (i, 1, q) {
		read (x); c = getchar ();
		a[++ m] = {x, c};
		if (!(i % B) || !(i ^ q)) sol ();
	}
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 21316kb

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
Time Limit Exceeded

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: