题意:编号为[0,2^n-1],问存在多少对编号(a,b)满足 a<b&& a^x > b^x
给出长度为n的二进制数x 答案模1e9+7. 1<=n<=100
二进制x中为0的位 进行异或时显然没有什么意义
对n==5的所有x进行打表 观察答案和1的个数是否存在规律?
给出长度为n的二进制数x 答案模1e9+7. 1<=n<=100
二进制x中为0的位 进行异或时显然没有什么意义
对n==5的所有x进行打表 观察答案和1的个数是否存在规律?
打表得 答案和(n,x)的关系为 ans=x*(2^(n-1))
正解:
若a<b, a^x>b^x 枚举a^x>b^x第一次发生的位置.
显然不可能出现在s[i]==0的位置.
若s[i]=='1' 那么(a,b) 的[0,i-1]位必须相同 a的第i位为0,b的第i位为1 ,[i+1,n-1]位任意取 所以(a,b)的对数为 2^i * 2^(2*(n-i-1))
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+5,mod=1e9+7;
bool vis[N];
int c[N],n=4;
void table()
{
for(int x=0;x<(1<<n);x++)
{
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
ll y=x,one=0,cnt=0;
while(y)
{
if(y&1)
one++;
y/=2;
}
for(int i=(1<<n)-1;i>=0;i--)
{
c[i^x]++;
for(int j=0;j<(i^x);j++)
cnt+=c[j];
}
// cout<<x<<' '<<one<<' '<<cnt<<endl;
}
}
ll pw[N];
int main()
{
// ans= x*2^(n-1)
pw[0]=1;
for(int i=1;i<N;i++)
pw[i]=(pw[i-1]*2ll)%mod;
string s;
cin>>s;
ll x=0,n=s.length();
for(int i=0;s[i];i++)
{
if(s[i]=='1')
x=(x+pw[n-i-1])%mod;
}
x=(x*pw[n-1])%mod;
cout<<x<<endl;
return 0;
}