[ABC390D] Stone XOR题解

思路

题面分析

这道题给了我们 n n n 个数,叫我们把其中的一些数加起来,求最后的异或和有多少种不同的答案,看到这里,大家应该还没有思路,但一看数据范围,就会发现,他的这个 n n n 给的特别小,因此我们可以考虑一个阶乘级的带剪枝的搜索。

搜索细节

在搜索的过程中,为了去掉最后统计答案的时间复杂度,我们采取边搜索边统计答案的方式。每次都从当前数的前面找要合并起来的数,而且要找的是其它数没有找到的。考虑他给的 a i a_i ai 特别大,最后去重还要用到 umap。这样勉强能卡过。

code

#include<bits/stdc++.h>
using namespace std;
long long n,a[200005],,f,ans;
unordered_map<long long,long long> mp;
void dfs(long long x,long long an){
	if(x>n){
		if(mp[an]==0) ans++;
		mp[an]++;
		return;
	}
	dfs(x+1,an^a[x]);
	for(int i=1;i<x;i++){
		if(a[i]!=0){
			long long y=a[i];
			a[i]=0;a[x]+=y;
			dfs(x+1,an^a[x]^y);
			a[i]=y;a[x]-=a[i]; 			
		}
	}
	return;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	dfs(1,0);
	cout<<ans<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值