自己的后几组数据卡在边缘通过(1.98~2.00)但是看大佬们总时长都在1s以内。想问问是代码优化问题,还是思路问题。 思路:将点权拆分为2进制,通过二进制dp每一位从子到父获取答案,并把每一个子树的答案存储在dp[i][62][0]
#include<bits/stdc++.h>
using namespace std;
long long int dp[500005][63][2],md=998244353,v[500005],x,y;
long long int t,n,tt,t1,t0,ans;
vector <int> mp[500005];
inline void bfs(int x){
for(int i=0;i<=61;i++){
if(v[x]&((long long int)1<<i))dp[x][i][1]=1;
else dp[x][i][0]=1;
}
for(int i=0;i<mp[x].size();i++){
bfs(mp[x][i]);
for(int j=0;j<=61;j++){
t1=dp[x][j][1];
t0=dp[x][j][0];
t0*=dp[mp[x][i]][62][0];
t0%=md;
t1*=dp[mp[x][i]][62][0];
t1%=md;
t0+=dp[x][j][0]*dp[mp[x][i]][j][0]+dp[x][j][1]*dp[mp[x][i]][j][1];
t0%=md;
t1+=dp[x][j][1]*dp[mp[x][i]][j][0]+dp[x][j][0]*dp[mp[x][i]][j][1];
t1%=md;
dp[x][j][1]=t1;
dp[x][j][0]=t0;
}
}
for(int i=0;i<=61;i++){
dp[x][62][0]+=dp[x][i][1]*(((long long int)1<<i)%md);
dp[x][62][0]%=md;
}
}
int main(){
//cout<<((long long int)1<<61);
cin>>n;
for(int i=1;i<=n;i++){
//cin>>v[i];
scanf("%lld",&v[i]);
//v[i]=(t%md);
}
for(int i=2;i<=n;i++){
//cin>>x;
scanf("%d",&x);
mp[x].push_back(i);
}
bfs(1);
cout<<dp[1][62][0];
return 0;
}