A. XOR Equation(dfs大法好哇)

x s 40 注意到x和s最大才40位二进制

? ! ! \color{Red}想到了什么?爆搜!!

40 从第40位二进制开始爆搜

x 1 , 1 \color{orange}当x的这一位是1,说明两个数字二进制在这位有且仅有一个是1

2 , 所以这里方案数乘上2,和加上这一位二进制继续往下搜


x 0 , 0 , 1 \color{Red}当x这一位是0,说明两个数字二进制在这位要么都是0,要么都是1

0 , 是0就什么都不加,继续往下搜

1 ( ) , 是1就加上这一位二进制的两倍(两个数),继续往下搜

剪枝

很好想,当两个数后面的二进制全都选1的和还是小于s,结束

当两个数和已经大于s,结束

细节

我们这样搜可能搜出某个数为0的情况

但题目要求是正数

所以搜的时候记录一下,有没有选过1,没得话就减掉

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fac[100009],s,x,pre[10009],ans;
void dfs(ll num,ll u,ll k,ll ok)//num是哪一位二进制,u表示当前总和 
{
	if( num==-1 )
	{
		if( u==s )
		{
			ans+=fac[k];
			if( !ok )	ans-=2;
		}
		return;
	}
	if( x&fac[num] )
		dfs(num-1,u+fac[num],k+1,ok);//一个选0,一个选1 
	else
	{
		int flag=0;
		if( u+2*fac[num]<=s )	flag=1,dfs(num-1,u+2*fac[num],k,1);//选1
		if( pre[num-1]*2+u>=s )	flag=1,dfs(num-1,u,k,ok);
	}
}
int main()
{
	fac[0]=1,pre[0]=1;
	for(int i=1;i<=40;i++)	fac[i]=2*fac[i-1],pre[i]=pre[i-1]+fac[i];
	cin >> s >> x;
	dfs(40,0,0,0);
	cout << ans;
} 

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107682503
xor