CSP-S 2019 括号树 题解
2026/8/5 8:00:24 网站建设 项目流程

这道题我准备按照考场上的思路从50分到100分写题解
开干!

50分的特例

当我们浏览完数据时,我们会发现有一个特殊性质:Fi=i-1。这就意味着这棵树退化为了一条链。这时,这道题就变成了一道DP模版题:括号匹配。(当然,还是要加一些处理)

#include<bits/stdc++.h>usingnamespacestd;longlongn,f[500005];longlongdp[500005],pos,ans,sum;longlongm;string s;intmain(){cin>>n;cin>>s;s=" "+s;for(longlongi=1;i<n;i++){cin>>f[i];}stack<longlong>st;for(longlongi=1;i<=n;i++){if(s[i]=='('){st.push(i);}else{if(!st.empty()){pos=st.top();st.pop();dp[i]=dp[pos-1]+1;}}}for(longlongi=1;i<=n;i++){sum+=dp[i];ans^=(sum*i);}cout<<ans;return0;}

70分

通过观察我们可以发现,当数据很小时,树状的我们可以暴力做出来,而链状的我们可以用线性DP做,这样可以拿下70分

#include<bits/stdc++.h>usingnamespacestd;longlongn,f[500005];longlongdp[500005],pos,ans,sum;longlongm;string s;vector<int>G[100005];charval[100005];boolcheck(string t){stack<int>st;for(intl=0;l<t.size();l++){if(t[l]=='('){st.push('(');}else{if(st.empty())returnfalse;st.pop();}}returnst.empty();}longlongxdp(){vector<longlong>dp(n+1,0);vector<int>st;longlongsum=0,ans=0;for(inti=1;i<=n;i++){if(s[i-1]=='('){st.push_back(i);dp[i]=0;}else{if(!st.empty()){intpos=st.back();st.pop_back();dp[i]=dp[pos-1]+1;}else{dp[i]=0;}}sum+=dp[i];ans^=(1ll*i*sum);}returnans;}longlongdfs(intu,string path){path.push_back(val[u]);intL=path.size();intk=0;for(intl=0;l<L;l++){for(intr=l;r<L;r++){string sub=path.substr(l,r-l+1);if(check(sub))k++;}}longlongans=1ll*u*k;for(inti=0;i<G[u].size();i++){intv=G[u][i];ans^=dfs(v,path);}returnans;}intmain(){cin>>n>>s;for(inti=0;i<n;i++){val[i+1]=s[i];}boolisf=true;vector<int>f(n+1);for(inti=2;i<=n;i++){cin>>f[i];if(f[i]!=i-1)isf=false;G[f[i]].push_back(i);}longlongans;if(isf){ans=xdp();}else{ans=dfs(1,"");}cout<<ans;return0;}

正解

其实之前我们已经几乎做完了,只用把线性DP与树结合在一起,做成一个树上DP就行了

#include<bits/stdc++.h>usingnamespacestd;intn,m;string s;vector<longlong>G[500005];longlongf[500005];longlongdp[500005];longlongsum=0,ans=0;vector<longlong>st;voiddfs(longlongu){longlongoldsum=sum;longlongm=-1;if(s[u-1]=='('){st.push_back(u);dp[u]=0;}else{if(!st.empty()){m=st.back();st.pop_back();dp[u]=dp[f[m]]+1;}else{dp[u]=0;}}sum+=dp[u];ans^=(1LL*u*sum);for(longlongi=0;i<(longlong)G[u].size();i++){dfs(G[u][i]);}sum=oldsum;if(s[u-1]=='('){st.pop_back();}else{if(m!=-1){st.push_back(m);}}}intmain(){cin>>n>>s;f[1]=0;for(inti=2;i<=n;i++){cin>>f[i];G[f[i]].push_back(i);}dfs(1);cout<<ans;return0;}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询