Recently, watashi finds a simple sequence S = {si} i >= 1 in a book. This sequence is determined by the following rules:
For each si, si is a positive integer.
It's an increasing sequence. For each i >= 1, we have si <= si + 1.
If x = 2a * b (x > 0, b % 2 != 0), we can find a different j (j1, j2, ..., ja) which satisfy sjk = x (1 <= k <= a). And if for all k, i != jk, then si != x.
So the sequence S = {2, 4, 4, 6, 8, 8, 8, 10, …}. Now watashi wants to know the sum of si (n <= i <= m). As a kind-hearted person, please help him to find out the answer.
Input
There are multiple test cases (about 80000).
For each case, there’s exactly one line which contains two integer n and m (1 <= n <= m <= 10^9) respectively.
Process to the end of the file.
Output
For each case, output the answer in a single line.
Sample Input
1 3
4 4
5 8
Sample Output
10
6
34
解题思路:数位DP,注意输出时要用%lld而不是%I64d。
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <utility>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
ll dp[40];
ll ss[40];
ll cal(ll x) {
ll t = 1, cnt = 0;
while(t <= x) t *= 2, cnt++;
t /= 2, cnt--;
ll ret = 0;
while(t) {
ll tmp = x / t;
tmp -= x / (t*2);
ret += (cnt+1) * tmp;
t /= 2;
cnt--;
}
return ret;
}
void init() {
memset(dp, 0, sizeof(dp));
dp[0] = 1;
ss[0] = 1;
for(int i = 1; i <= 30; ++i) {
dp[i] = cal(1LL<<i);
ss[i] = ss[i-1] + dp[i];
}
return ;
}
ll getsum(ll x) {
if(x%2 == 0) x--;
return (x+1)*(x/2+1)/2;
}
ll sum(ll x) {
ll ret = 0;
ll cnt = 1;
ll t = 2;
while(x) {
ret += t * cnt * getsum(x);
x /= 2;
cnt++;
t *= 2;
}
return ret;
}
int main() {
init();
ll a, b;
ll x1, x2, y1, y2;
while(scanf("%lld %lld", &a, &b) != EOF) {
a--;
ll ta = a;
ll tb = b;
x1 = 0;
x2 = 0;
for(int i = 30; i >= 0; --i) {
if(ta <= 0) break;
if(i > 0) {
if(ss[i-1] < ta) {
x1 |= (1LL<<i);
ta -= dp[i];
}
} else {
if(dp[i] >= ta) {
x1 |= (1LL<<i);
}
}
}
for(int i = 30; i >= 0; --i) {
if(tb <= 0) break;
if(i > 0) {
if(ss[i-1] < tb) {
x2 |= (1LL<<i);
tb -= dp[i];
}
} else {
if(dp[i] >= tb) {
x2 |= (1LL<<i);
}
}
}
ll t1 = cal(x1);
ll t2 = cal(x2);
if(t1 >= a) {
y1 = t1 - a;
}
if(t2 >= b) {
y2 = t2 - b;
}
ll ans1 = sum(x1);
ll ans2 = sum(x2);
ans1 -= 2*y1 * x1;
ans2 -= 2*y2 * x2;
printf("%lld\n", ans2 - ans1);
}
return 0;
}