树上深搜
2026-08-18 16:18:11
发布于:广东
4阅读
0回复
0点赞
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll n;
vector<ll>a[100005];
ll b[100005];
string s;
void dfs(ll idx, ll pre)//idx代表当前所处在哪个点
{ //pre代表因为上方导致这个点需要的变化次数(因为是题目是一个点及对应整个子树都要变化)
// &1作用是判断最后一位数是1还是0,也就是判断是奇数还是偶数
if ((pre + b[idx]) & 1)//pre是因为上面的点所导致要变化的次数,b[idx]是当前的点所需要的变化
// 总的操作次数是奇数时则需要变化
s[idx] = s[idx] == '0' ? '1' : '0';//是1则变0 是0则变1
//cout<<"s[idx]结束="<<s[idx]<<endl;
for (auto to : a[idx])//遍历这个点的孩子叫to
dfs(to, pre + b[idx]);//深搜递归去到to这个点,to受到上面点所需要修改次数就是其父节点的总修改次数
//所以dfs(to,pre+b[idx])
}
int main()
{
cin >> n;
for (ll i = 2;i <= n;i++)
{
ll fa;cin >> fa;
a[fa].push_back(i);//a[父节点].push_back(孩子)
}
cin >> s;
s = " " + s;//垫个空格,第i个字符就是s[i]
ll q;cin >> q;
while (q--)
{
ll idx;cin >> idx;
b[idx]++;//记录这个位置需要变化次数+1
}
dfs(1, 0);//从根节点1开始,由上方导致的修改次数为0(根节点没有父节点)
for(int i = 1;i<=s.size()-1;i++)//别忘记垫了个空格 遍历下标范围需要调整
cout<<s[i];
return 0;
}
这里空空如也


有帮助,赞一个