剪枝
很好想,当两个数后面的二进制全都选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;
}