计蒜客 - 42578 And and Pair(2019 ICPC南昌)(找规律水题)

题目
Given an extremely large non-negative integer n, you are asked to count the number of pairs (i,j) of integers satisfying the following conditions:

0≤j≤i≤n;
i & n=i; and
i & j=0.
Here & represents the bitwise AND operator.

For simplicity, the binary representation of n will be given. Meanwhile, you only need to output the answer modulo (109+7).

Input
The first line contains an integer T (1≤T≤20) indicating the number of test cases.

Each of the following T lines contains a string S (1≤|S|≤105)
which is the binary representation of the non-negative integer n. Note that leading zeros of S could appear in the input.

Output
For each test case, output a line containing the answer described above modulo (109+7).

题意
给一个二进制数n 求满足
(1)0≤j≤i≤n;
(2)i & n=i;
(3)i & j=0.
这三个条件的所有数对(i,j)的数量

思路
关于第二个条件,对于n的每个为0的二进制位,i的对应二进制位也应为0。关于第三个条件,对于i的每个位1的二进制位,j的对应二进制位应该为0。得到这两个信息后我们不妨尝试找规律。最后结论为:
对于二进制数n,从右向左数,第i个1,其位于整个数的第k位,其贡献为3i-1+2k-1,答案就是所有的1的贡献加上1(没有算上i和j均为0这个数对)。

代码

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

const int MAXN = 2e5 + 5;
const ll mod = 1e9 + 7;
int t, n, m, k, flag = 1;
string s;

ll qukpow_2(int b) {
	ll x = 2, ret = 1;
	while(b) {
		if(b&1) ret = ret * x % mod;
		x = x * x % mod;
		b >>= 1;
	}
	return ret;
}

int main(void) {
	IO;
	cin >> t;
	while(t--) {
		cin >> s;
		int len = s.size();
		ll ans = 1, now = 0;
		for(int i = len - 1; i >= 0; i--) {
			if(s[i] == '1') {
				if(now) {
					now = now * 3 % mod;
					ans += now;
					ans = ans % mod;
				}else {
					now = qukpow_2(len - 1 - i);
					ans += now;
					ans = ans % mod;
				}
			}else {
				now = now * 2 % mod;
			}
		}
		cout << ans << '\n';
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值