题意一开始看错了想半天不知道他在说什么
要求最小编号,异或和,数目,应该只能把关键叶节点全部找出来才能求
找这些节点的话,好像只能把所有最小黑方胜集合的并集和所有最小白方胜集合的并集找出来求交集
然后dfs下去很好找的吧,是个树形DP?,要保存每个节点的信息可以用一个树的结构,就是每个节点向对它贡献的节点连边,然后这个节点的信息递归下去找就行
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;
const int maxn = 410000;
struct edge
{
int y,nex;
edge(){}
edge(int _y,int _nex){y=_y;nex=_nex;}
}a[maxn]; int len,fir[maxn];
int n;
void ins(int x,int y){a[++len]=edge(y,fir[x]); fir[x]=len;}
struct node
{
int y,nex;
node(){}
node(int _y,int _nex){y=_y;nex=_nex;}
}te[maxn<<2]; int tot,fi[maxn];
void inst(int x,int y){te[++tot]=node(y,fi[x]); fi[x]=tot;}
int s[2][maxn];
int q[maxn<<2],nex[maxn<<2],tail[maxn],tt;
void dfs(int x,int col)
{
if(!fir[x])
{
s[0][x]=1;
s[1][x]=1;
return ;
}
int mn; mn=inf;
for(int k=fir[x];k;k=a[k].nex)
{
int y=a[k].y;
dfs(y,1^col);
if(s[col][y]<mn)
{
mn=s[col][y];
q[x]=y; nex[x]=-1; tail[x]=x;
}
else if(s[col][y]==mn) { q[++tt]=y; nex[tail[x]]=tt; tail[x]=tt; nex[tt]=-1; }
s[col^1][x]+=s[col^1][y];
inst((x<<1)|(col^1),(y<<1)|(col^1));
}
s[col][x]=mn;
for(int y=x;y!=-1;y=nex[y])
inst((x<<1)|col,(q[y]<<1)|col);
}
bool v[2][maxn];
void find_(int x,int col)
{
if(!fi[x]) { v[col][x>>1]=true; return ; }
for(int k=fi[x];k;k=te[k].nex)
{
int y=te[k].y;
find_(y,col);
}
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
int x; scanf("%d",&x);
ins(x,i);
}
tt=n;
dfs(1,1);
find_(2,0);
find_(3,1);
int mnx=-1,orx=0,sum=0;
for(int i=1;i<=n;i++)
if(v[0][i]&&v[1][i])
{
if(mnx==-1) mnx=i;
orx^=i;
sum++;
}
printf("%d %d %d\n",mnx,sum,orx);
return 0;
}