2019 ICPC 南昌站 And and Pair
个人感觉是一个分类讨论的题目
首先题目要求 :
给出一个n,求(i, j)的个数
0 <= j <= i <= n
i & n = i
i & j = 0
从低位向高位访问,如果出现1的话,并有x个1,y个0。
那么进行分类讨论,除最高位的1之外所有位来说
如果 i = 1,j 可以为 0(对于i和j的同一位来说)
如果 i = 0,j 可以为 0 。
如果 i = 0,j 可以为 1 的前提为 i 的最高位为 1 ,因为 j <= i。
以上为 i 当前最高位为 1 的情况。
如果 i 的最高位不为 1 ,那么 i 的最高位为 0 ,符合条件的 j 最高位也只能为 0 ,那么就该位就无效了(因为全是0,忽略前导零的话)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define mod 1000000007
#define ll long long
const int N = 100010;
ll z2[N], z3[N];
char ch[N];
int main(){
z2[0] = 1ll;
z3[0] = 1ll;
for(int i = 1;i < N;i ++) {
z2[i] = z2[i - 1] * 2ll;
z2[i] %= mod;
z3[i] = z3[i - 1] * 3ll;
z3[i] %= mod;
}
int _;
scanf("%d", &_);
while(_--) {
scanf("%s",ch);
int l = strlen(ch);
ll ans = 1;
int l0 = 0, l1 = 0;
for(int i = l - 1;i >= 0;i --) {
if(ch[i] == '1') {
ans += (ll)z2[l0] * z3[l1];
ans %= mod;
l1 ++;
}
else l0 ++;
}
printf("%lld\n",ans);
}
return 0;
}
初始化数组得开 longlong ,因为(1e9 + 7)* 3 爆 int