https://atcoder.jp/contests/arc148/tasks/arc148_c
输入 n(2≤n≤2e5) q(≤2e5),然后输入 p2,p3,…,pn 表示一棵根为 1 的树,pi 表示点 i 的父节点。
然后输入 q 个询问,每个询问先输入 m,然后输入 m 个互不相同的特殊节点 v1,v2,…,vm。所有询问的 m 之和不超过 2e5。
每个节点都有一盏灯,其中特殊节点的灯打开,其余节点的灯关闭。
每次操作,你可以选择一棵子树,切换子树内所有灯的开/闭状态。
对每个询问,回答:要使所有灯关闭,至少需要多少次操作
按下自身和其孩子节点就可以实现翻转,这样一来,有父子关系的点就被按了两下
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n, q;
int cnt[N];
int p[N];
int main ()
{
cin >> n >> q;
for(int i = 2; i <= n; i ++){
int x;
cin >> x;
cnt[x] ++;
p[i] = x;
}
while(q --){
int m;
cin >> m;
vector<int> v;
unordered_map<int,bool> hs;
while(m --){
int x;
cin >> x;
v.push_back(x);
hs[x] = true;
}
int ans = 0;
for(auto &x : v) ans += cnt[x] + 1;
for(auto &x : v){
if(hs[p[x]]) ans -= 2;
}
cout << ans << endl;
}
return 0;
}