题目描述:
给出一个数字 N (以二进制形式给出)
然后寻找数对 (i,j) 满足
1:1<=j<=i<=n
2:i&n=i
3:j&i=0
题目分析:
首先 第二个条件
对于 n 中的二进制0位置i只能取0,1位置 i 可以取 1 或者 0
对于 i 的1位置,j只能取 0 ,对于 i 的0位置 j可以取 1 或者 0
对于 j<=i这个条件 我们只需要让j取到的最高1位置小于i的最高一位置就行了
所以我们从小到大枚举N的二进制位数
当我们找到1的时候,以这个位置作为最高位即可
设 X为当前1的数量(不包括最高位),Y为当前0的数量
答案即为
不要忘了 全是0的一种情况。
题目链接:
AC代码:
#include <cstdio>
#include <iostream>
#include <cstring>
const int maxm=1e5+100;
const int mod=1e9+7;
long long num3[maxm],num2[maxm];
char s[maxm];
int main()
{
int t;
scanf("%d",&t);
num3[0]=num2[0]=1ll;
for(int i=1;i<=100000;i++) num2[i]=(num2[i-1]*2ll)%mod,num3[i]=(num3[i-1]*3ll)%mod;
while(t--)
{
long long ans=0;
scanf("%s",s);
int len=strlen(s);
int x=0,y=0;
for(int i=len-1;i>=0;i--)
{
if(s[i]=='1')
{
ans=(ans+(num3[x]*num2[y])%mod)%mod;
x++;
}
else y++;
}
ans=(ans+1)%mod;
printf("%lld\n",ans);
}
return 0;
}