2 条题解
-
2
#include <stack> #include <cstdio> using namespace std; int getbra() { char c; while((c=getchar())!='(' && c!=')') ; return c=='('; } int beg[500005]; int ed[500005]; int nxt[500005]; int top; void addedge(int a,int b) { ++top; ed[top] = b; nxt[top] = beg[a]; beg[a] = top; } stack<int> rb; // 记录未匹配的右括号位置 int rbi[500005]; // 方便还原 int sufi[500005]; // 以这个位置结束的合法括号后缀的个数 int pos; long long lastans; long long ins(int br) { ++pos; if(br) //( { rb.push(pos); rbi[pos] = sufi[pos] = 0; return lastans; } else { if(rb.empty()) { rbi[pos] = 0; sufi[pos] = 0; return lastans; } else { int r = rb.top(); rb.pop(); rbi[pos] = r; sufi[pos] = sufi[r-1]+1; // 右括号前一个的合法后缀现在都是合法后缀,然后多一个单独一个的括号后缀 lastans += sufi[pos]; return lastans; } } } void erase(int br) { if(br) { rb.pop(); } else { if(rbi[pos]) { rb.push(rbi[pos]); lastans -= sufi[pos]; } } --pos; } int bri[500005]; long long ansi[500005]; void dfs(int x) { ansi[x] = ins(bri[x]); for(int p=beg[x]; p; p=nxt[p]) { dfs(ed[p]); } erase(bri[x]); } int main() { int n; scanf("%d",&n); for(int i=1; i<=n; ++i) { bri[i] = getbra(); } for(int i=2; i<=n; ++i) { int fa; scanf("%d",&fa); addedge(fa,i); } dfs(1); long long ans = 0; for(int i=1; i<=n; ++i) { ans ^= i*ansi[i]; } printf("%lld\n",ans); }
信息
- ID
- 2
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 24
- 已通过
- 15
- 上传者