P9745 「KDOI-06-S」树上异或
P9745 「KDOI-06-S」树上异或
参考:https://www.luogu.com.cn/blog/710100/p9745-kdoi-06-s-shu-shang-yi-huo-jian-yao-ti-xie
其中,转移中一部分考虑的是断边,那么两部分分离,乘法原理;如果连边,需要异或为0,就00或11,为1,就01或10.按位分离计算,最后的f就是综合起来。
#include<iostream>
#include<cstring>
using namespace std;
const int mod=998244353,N=500010,P=60;
typedef long long ll;
ll a[N];
int f[N],p2[N],g[N][P][2],n,h[N],e[N],ne[N],idx;//don't forget memset h!
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int x){
for(int i=h[x];~i;i=ne[i]){
int j=e[i];
dfs(j);
for(int k=0;k<P;++k){
int x0=g[x][k][0],x1=g[x][k][1];
int j0=g[j][k][0],j1=g[j][k][1];
g[x][k][0]=(1ll*x0*f[j]%mod+1ll*x0*j0%mod+1ll*x1*j1%mod)%mod;
g[x][k][1]=(1ll*x1*f[j]%mod+1ll*x0*j1%mod+1ll*x1*j0%mod)%mod;
}
}
for(int k=0;k<P;++k)f[x]=(f[x]+1ll*p2[k]*g[x][k][1]%mod)%mod;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
p2[0]=1;
for(int i=1;i<P;++i)p2[i]=(p2[i-1]<<1)%mod;
memset(h,-1,n*4+4);
for(int i=1;i<=n;i++){
cin>>a[i];
for(int k=0;k<P;++k)g[i][k][a[i]>>k&1]=1;
}
for(int i=2;i<=n;i++){
int x;
cin>>x;
add(x,i);
}
dfs(1);
cout<<f[1]<<'\n';
}
本文作者:wscqwq
本文链接:https://www.cnblogs.com/wscqwq/p/17775637.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话