注意注释中*****部分!不能不加i==1
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
long long dp[30][30][30];
int digit[30];
long long DFS( int pos, int pre_1, int pre_0, bool limit, bool pre_all_0 ){
if( pos == 0 ){
return pre_0 >= pre_1;
}
if( !limit && dp[pos][pre_1][pre_0] != -1 && !pre_all_0 ){
return dp[pos][pre_1][pre_0];
}
int end = limit ? digit[pos] : 1;
long long sum = 0;
for( int i = 0; i <= end; i++ ){
int temp1, temp0;
if( !pre_all_0 ){
temp1 = pre_1 + (int)( i == 1 );
temp0 = pre_0 + (int)( i == 0 );
}else{
temp1 = pre_1 + (int)( i == 1 );/*****************
temp0 = pre_0;
}
sum += DFS( pos - 1, temp1, temp0, limit && i == end, pre_all_0 && i == 0 );
}
if( !limit && !pre_all_0 ){
dp[pos][pre_1][pre_0] = sum;
}
return sum;
}
long long solve( long long N ){
int len = 32;
for( int i = 31; i >= 0; i-- ){
if( ( 1 << i ) & N ){
digit[i+1] = 1;
}else{
digit[i+1] = 0;
}
}
while( digit[len] == 0 && len > 0 ){
len--;
}
return DFS( len, 0, 0, true, true );
}
int main(){
long long A, B;
memset( dp, -1, sizeof( dp ) );
while( cin >> A >> B ){
cout << solve( B ) - solve( A - 1 ) << endl;
}
return 0;
}