求助
查看原帖
求助
360140
QWXSDL楼主2023/10/15 19:02
using namespace std;
long long n,x[510000],f[510000],ans=0,shu[510000],sum[510000],anss=0;
struct bcj{
	long long fa,q;
}d[510000];
/*
f【i】:i点与f[i]点相连接,若f[i]=0,则意味着其边已经被删 
 
思路:先用深搜遍历每一个点将其删除:
从2点开始,若该点与0连接,则意味着其为父节点 
 
每遍历一次,进行一次探测
查看该有多少个图
后将每个集合进行乘法 
*/
int findd(int xx){
	if(xx!=d[xx].fa){
		d[xx].fa=findd(d[xx].fa);
	}
	return d[xx].fa;
}
void che(){
	int k=0;
	memset(sum,-1,sizeof(sum));
	memset(shu,0,sizeof(shu));
	for(int i=1;i<=n;i++){
		findd(i);
	}
	k++;
	shu[k]=1;
	for(int i=2;i<=n;i++){
		if(d[i].fa==i){
			k++;
			shu[k]=i;
		}
	}
	ans=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=k;j++){
			if(d[i].fa==shu[j]){
				if(sum[j]==-1){
					sum[j]=d[i].q%998244353;
				}else{
					sum[j]=sum[j]^d[i].q%998244353;
				}
			}
			
		}
	}
	for(int i=1;i<=k;i++){
		ans=(ans*sum[i])%998244353;
	}
	anss=anss%998244353+ans%998244353;
}
void chong(){
	d[1].fa=1;
	f[1]=1;
	for(int j=2;j<=n;j++){
		d[j].fa=f[j];
	}
}
void dfs(int x){
	if(d[x].fa==0||x>n)return;
	for(int i=x;i<=n;i++){
		int ff=d[i].fa;
		d[i].fa=i;
		f[i]=i;
		che();
		chong();
		dfs(i+1);
		d[i].fa=ff;//为了让他进行下次遍历时数不变
		f[i]=ff; 
	}
}
int main(){
	cin>>n;
	d[1].fa=1;
	f[1]=1;
	for(int i=1;i<=n;i++){
		cin>>x[i];
		d[i].q=x[i];
	}
	for(int j=2;j<=n;j++){
		cin>>f[j];
		d[j].fa=f[j];
	}
	che();
	chong();
	dfs(2);
	cout<<anss;
	return 0;
}```
2023/10/15 19:02
加载中...