传送门
- 题意:求[A,B]间的round数的个数。
- round数:划为标准二进制形式之后0的个数大于等于1的个数
- 1<=A,B<=2e9
- 题解:
- 怎么设置数组dp?DP[pos][k1][k2],k1,k2分别表示0和1的个数
- 怎么处理前导0,多设置一个像limit的标记数组lead就ok了(地位和limit一样,但是还与k1,k2的值有关)。处理前导0也是比较模板的东西
- 代码:
#include <cstring>
#include <iostream>
#include <string>
#define dbg(x) cout << #x << "===" << x << endl
using namespace std;
int dp[40][40][40];
int a[40], cnt;
int dfs(int pos, int k1, int k2, bool lead, bool limit) {
if (pos == -1) return k1 >= k2;
if (!limit && !lead && dp[pos][k1][k2] != -1) return dp[pos][k1][k2];
int res = 0;
int up = limit ? a[pos] : 1;
for (int i = 0; i <= up; i++) {
res += dfs(pos - 1, lead ? 0 : (k1 + !i), k2 + i, lead && (i == 0),
limit && (i == a[pos]));
}
if (!limit && !lead) dp[pos][k1][k2] = res;
return res;
}
int solve(int x) {
cnt = 0;
while (x) {
a[cnt++] = x % 2;
x /= 2;
}
return dfs(cnt - 1, 0, 0, true, true);
}
signed main() {
memset(dp, -1, sizeof(dp));
int l, r;
while (cin >> l >> r) {
int ans = solve(r) - solve(l - 1);
cout << ans << endl;
}
return 0;
}