#include<cstdio>#include<cstring>#include<algorithm>#include<set>#include<vector>typedeflonglong s64;
using std::set;
typedefset<int>::iterator iter;
using std::vector;
template <classT>inlinevoidread(T &x) {
staticchar s;
while (s = getchar(), s < '0' || s > '9');
x = s - '0';
while (s = getchar(), s >= '0' && s <= '9') x = x * 10 + s - '0';
}
voidtense(int &x, constint &y) {
if (x < y) x = y;
}
voidrelax(int &x, constint &y) {
if (x > y) x = y;
}
constint N = 500100;
int n;
char s[N];
int anc[19][N];
int tot, head[N], ver[N], Next[N];
voidadd_edge(int u, int v) {
ver[++ tot] = v; Next[tot] = head[u]; head[u] = tot;
}
int pre[N];
int dep[N];
int g[19][N];
voiddfs1(int u) {
pre[u] = pre[anc[0][u]] + (s[u] == '(' ? -1 : 1);
dep[u] = dep[anc[0][u]] + 1;
for (int i = 1; i <= 18; i ++) anc[i][u] = anc[i - 1][anc[i - 1][u]];
g[0][u] = pre[anc[0][u]];
for (int i = 1; i <= 18; i ++) tense(g[i][u] = g[i - 1][u], g[i - 1][anc[i - 1][u]]);
for (int i = head[u]; i; i = Next[i]) {
int v = ver[i];
dfs1(v);
}
}
namespace SA {
int m = 2;
int sa[N], rk[N], height[N];
int cnt[N], id[N], px[N];
int anc_rk[19][N];
intget_LCP(int x, int y) {
int cur = 0;
for (int i = 18; i >= 0; i --) {
if (std::min(dep[x], dep[y]) < (1 << i)) continue;
if (anc_rk[i][x] ^ anc_rk[i][y]) continue;
x = anc[i][x], y = anc[i][y], cur ^= (1 << i);
}
return cur;
}
boolsame(int x, int y, int k) {
int p = anc[k][x] ? anc_rk[k][anc[k][x]] : -1;
int q = anc[k][y] ? anc_rk[k][anc[k][y]] : -1;
return anc_rk[k][x] == anc_rk[k][y] && p == q;
}
voidbuild() {
for (int i = 1; i <= n; i ++) rk[i] = (s[i] == '(' ? 1 : 2);
for (int i = 1; i <= n; i ++) cnt[rk[i]] ++;
for (int i = 1; i <= m; i ++) cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i --) sa[cnt[rk[i]] --] = i;
for (int k = 0, p = 0; (1 << k) < n; k ++, m = p) {
for (int i = 0; i <= m; i ++) cnt[i] = 0;
for (int i = 1; i <= n; i ++) cnt[px[i] = rk[anc[k][i]]] ++;
for (int i = 1; i <= m; i ++) cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i --) id[cnt[px[i]] --] = i;
for (int i = 0; i <= m; i ++) cnt[i] = 0;
for (int i = 1; i <= n; i ++) cnt[px[i] = rk[id[i]]] ++;
for (int i = 1; i <= m; i ++) cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i --) sa[cnt[px[i]] --] = id[i];
for (int i = 1; i <= n; i ++) anc_rk[k][i] = rk[i];
p = 0;
for (int i = 1; i <= n; i ++) rk[sa[i]] = same(sa[i - 1], sa[i], k) ? p : ++ p;
}
for (int i = 1; i <= n; i ++) rk[sa[i]] = i;
for (int i = 2; i <= n; i ++) height[i] = get_LCP(sa[i - 1], sa[i]);
}
}
namespace ST {
int logx[N];
int f[19][N];
voidbuild() {
logx[0] = -1;
for (int i = 1; i <= n; i ++) logx[i] = logx[i >> 1] + 1;
for (int i = 1; i <= n; i ++) f[0][i] = SA::height[i];
for (int j = 1; j <= 18; j ++)
for (int i = 1; i <= n - (1 << j) + 1; i ++)
relax(f[j][i] = f[j - 1][i], f[j - 1][i + (1 << (j - 1))]);
}
intquery(int l, int r) {
int k = logx[r - l + 1];
returnstd::min(f[k][l], f[k][r - (1 << k) + 1]);
}
}
set<int> G;
intfind_h(int x) {
iter w = G.lower_bound(x);
int cur = 0;
if (w != G.end())
tense(cur, ST::query(x + 1, *w));
if (w != G.begin())
tense(cur, ST::query(*(-- w) + 1, x));
return cur;
}
intfind_m(int u) {
int x = u;
for (int i = 18; i >= 0; i --)
if (dep[x] >= (1 << i) && pre[u] >= g[i][x]) x = anc[i][x];
return x;
}
vector<int> pos[N * 2];
s64 ans[N];
voiddfs2(int u) {
int l = dep[find_m(u)] + 1, r = dep[u] - find_h(SA::rk[u]);
pos[n + pre[anc[0][u]]].push_back(dep[u]);
G.insert(SA::rk[u]);
ans[u] = ans[anc[0][u]];
if (s[u] == ')') {
if (l <= r) {
vector<int> &V = pos[n + pre[u]];
ans[u] += upper_bound(V.begin(), V.end(), r) - lower_bound(V.begin(), V.end(), l);
}
}
for (int i = head[u]; i; i = Next[i]) {
int v = ver[i];
dfs2(v);
}
pos[n + pre[anc[0][u]]].pop_back();
G.erase(SA::rk[u]);
}
intmain() {
read(n);
scanf("%s", s + 1);
for (int i = 2; i <= n; i ++)
read(anc[0][i]), add_edge(anc[0][i], i);
dfs1(1);
SA::build();
ST::build();
dfs2(1);
s64 res = 0;
for (int i = 1; i <= n; i ++) res ^= (ans[i] * i);
printf("%lld\n", res);
return0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效