2 条题解
-
0
#include<cstdio> #include<iostream> #include<cstring> #include<stack> #include<vector> #include<algorithm> #define LL long long using namespace std; int read() { int f = 1,x = 0;char s = getchar(); while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();} while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();} return x * f; } LL lmax(LL a,LL b) { return a > b ? a : b; } LL lmin(LL a,LL b) { return a < b ? a : b; } vector<int> g[500005]; char c[500005]; LL as[500005]; LL sum[500005]; int f[500005]; int d[500005]; int n,m,i,j,s,o,k; stack<int> st; stack<int> ps; void dfs(int x,int ad) { int fa = f[x]; d[x] = d[fa] + 1; sum[x] = sum[fa];as[x] = 0; if(c[x] == '(') st.push(x); else { if(!st.empty()) { int p = st.top(); st.pop(); ps.push(p); ad ++; as[x] += as[f[p]] + 1; } else as[x] = 0; } sum[x] += as[x]; for(int i = 0;i < g[x].size();i ++) { dfs(g[x][i],ad); while(!st.empty() && d[st.top()] > d[x]) st.pop(); while(ps.size() > ad && d[ps.top()] > d[x]) ps.pop(); while(ps.size() > ad) st.push(ps.top()),ps.pop(); } return ; } int main() { n = read(); scanf("%s",c + 1); for(int i = 2;i <= n;i ++) { scanf("%d",&s); g[s].push_back(i); f[i] = s; } dfs(1,0); LL ans = 0; for(LL i = 1;i <= n;i ++) { ans ^= (i * sum[i]); } printf("%lld\n",ans); return 0; }
-
0
#include <bits/stdc++.h> #define ll long long #define mod1 992244353 using namespace std; const int N=500005; ll ans[N],xx,f[N]; int n,m,k,s,t,fa[N]; char c[N]; vector<int> e[N]; stack<int> st; void dfs(int u){ int kk=-1; if (c[u]=='('){//左括号,将编号压入栈 st.push(u); } else {//右括号,栈非空的情况下找到匹配的左括号了 if (!st.empty()){ kk=st.top();//记录被删去的左括号编号 f[u]=f[fa[kk]]+1; st.pop(); } } ans[u]=ans[fa[u]]+f[u];//更新答案 xx^=ans[u]*u; for (int v:e[u]){//遍历子节点 fa[v]=u; dfs(v); } //回溯之前还原当前括号的影响 if (kk!=-1) st.push(kk);//还原被删去的左括号编号 else if (c[u]=='(') st.pop();//是左括号,则直接出栈 } int main(){ cin>>n; cin>>c+1; for (int i=2;i<=n;++i){ cin>>k; e[k].push_back(i); } dfs(1); cout<<xx<<endl; }
- 1
信息
- ID
- 290
- 时间
- 1000ms
- 内存
- 250MiB
- 难度
- 3
- 标签
- 递交数
- 51
- 已通过
- 28
- 上传者