题目链接:https://nanti.jisuanke.com/t/48485
解题思路
简单版本暴力可过,中等版本可用O(nlogn)的算法过,我用的是dsu on tree,我们统计答案的时候,需要记一个map为每层每个值有几个,当我们找到一个节点 i ,可以与其贡献答案的点对为值为x^w[i]的点,所以遇到后当前层数能贡献答案的点对+当前层值为x^w[i]的点的数量,如果之前该层无贡献,则该层对 f 贡献+1。至于删除,就和加是对应的。
dsu on tree常数太大,卡不过困难版本,至于O(n)的做法,我还不会(太弱了QAQ),等啥时候会了再补可能学不会了 。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int N=1e6+5;
int n,x;
ll ans;
int w[N];
int dep[N],l[N],r[N],son[N],siz[N],reg[N];
int f,has[N];
int dfn,skp;
map<int,map<int,int > >mp;
struct node
{
int to,next;
}edge[N];
int head[N];
int cnt;
int read()
{
char ch;
int res=0;
int sign=1;
while((ch=getchar())>'9'&&ch<'0')
if(ch=='-')
sign=-1;
res=ch-'0';
while((ch=getchar())<='9'&&ch>='0')
res=res*10+ch-'0';
return res;
}
void add(int x,int y)
{
edge[++cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt;
}
void dfs(int u,int fa)
{
dep[u]=dep[fa]+1;
l[u]=++dfn;
reg[dfn]=u;
siz[u]=1;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
dfs(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[v]>siz[son[u]])
son[u]=v;
}
r[u]=dfn;
}
void get_ans(int u)
{
for(int i=l[u];i<=r[u];++i)
{
if(reg[i]==skp)
{
i=r[skp];
continue;
}
int weight=w[reg[i]];
int depth=dep[reg[i]];
if(mp[depth][weight^x])
{
if(!has[depth])
f++;
has[depth]+=mp[depth][weight^x];
}
mp[depth][weight]++;
}
}
void dele(int u)
{
for(int i=l[u];i<=r[u];++i)
{
if(reg[i]==skp)
{
i=r[skp];
continue;
}
int weight=w[reg[i]];
int depth=dep[reg[i]];
mp[depth][weight]--;
if(mp[depth][weight^x])
{
has[depth]-=mp[depth][weight^x];
if(!has[depth])
f--;
}
}
}
void dsu(int u,int fa,bool del)
{
//puts("1");
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(v==son[u])
continue;
//cout<<u<<" "<<v<<endl;
dsu(v,u,1);
//cout<<u<<" "<<v<<endl;
}
if(son[u])
{
dsu(son[u],u,0);
skp=son[u];
}
get_ans(u);
ans=(ans+(u^(n-f)))%mod;
//cout<<u<<" "<<f<<endl;
if(del)
{
skp=0;
dele(u);
}
}
int main()
{
n=read();
x=read();
for(int i=2;i<=n;++i)
{
int y;
y=read();
add(y,i);
}
for(int i=1;i<=n;++i)
w[i]=read();
dfs(1,0);
dsu(1,0,0);
printf("%lld",ans);
return 0;
}