题目链接:http://codeforces.com/gym/101128
题目大意:给你一个区间[x,y],找出这个区间有多少个seldom的数字。
seldom的数字定义如下:该数值的二进制数字符合如下条件ABAB...ABAB 或者 ABABA....BA,其中A表示连续的1的个数,B表示连续的0的个数。
思路:因为长度只有63,本来以为是数位dp的,想了想直接暴力预处理就好了
//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") LL x, y; vector<LL> ve; void solve(LL tmp, LL tmp1, LL i, LL j, int len){ int cnt = 1; while (true){ if (cnt % 2 == 1){ cnt++; if (len + i > 63) break; len += i; tmp = tmp << i; tmp += tmp1; ve.pb(tmp); } else { cnt++; if (len + j > 63) break; len += j; tmp = tmp << j; ve.pb(tmp); } //printf("tmp = %lld ", tmp); } } void init(){ for (int i = 1; i <= 63; i++){///这个是1的东西 LL tmp1 = 0; for (int f = 0; f < i; f++){ tmp1 |= (1LL << f); } ve.pb(tmp1); for (int j = 1; j <= 63; j++){///这个是0的东西 if (i + j > 63) break; LL tmp = tmp1 << j; ve.pb(tmp); solve(tmp, tmp1, i, j, i + j); } } sort(ALL(ve)); } int main(){ init(); while (scanf("%lld%lld", &x, &y) == 2){ int lb = lower_bound(ve.begin(), ve.end(), x) - ve.begin(); int rb = upper_bound(ve.begin(), ve.end(), y) - ve.begin(); printf("%d ", rb - lb); } return 0; }