0w1

HR 2's complement ( Digit DP )

https://www.hackerrank.com/challenges/2s-complement
It's easy to count the number of 1s that will be written in positive range with digit DP, simply remember the number of ways to reach some state will do. Let's think about cases where it's negative. With some observation, we will find that seeing 0s as 1s and vice versa, -1 is equivalent to 0, -2 to 1, x to -x - 1.

#include <bits/stdc++.h>
using namespace std;

#define int long long

typedef long long ll;
typedef pair< int, int > pii;
typedef vector< int > vi;
typedef vector< vi > vvi;
typedef vector< pii > vpii;
typedef vector< char > vch;

const int MOD7 = 1e9 + 7;
const int INF = 0x3f3f3f3f;

#define MULTIPLE_CASES

vi int_to_bin( int x ){
    vi res;
    stack< int > stk;
    while( x > 0 )
        stk.push( x & 1 ),
        x >>= 1;
    while( not stk.empty() )
        res.push_back( stk.top() ),
        stk.pop();
    return res;
}

ll getCount( int x, bool inc ){
    vi s = int_to_bin( x );
    vector< vector< ll > > dp( 33, vector< ll >( 2 ) );
    vector< vector< ll > > ways( 33, vector< ll >( 2 ) );
    ways[ 0 ][ 0 ] = 1;
    for( int i = 0; i < s.size(); ++i )
        for( int j = 0; j < 2; ++j )
            for( int d = 0; d < ( j ? 2 : s[ i ] + 1 ); ++d ) if( ways[ i ][ j ] )
                ways[ i + 1 ][ j || d < s[ i ] ] += ways[ i ][ j ],
                dp[ i + 1 ][ j || d < s[ i ] ] += dp[ i ][ j ] + ways[ i ][ j ] * d;
    ll res = 0;
    for( int i = 0; i < 2; ++i ){
        if( !i && !inc ) continue;
        res += dp[ s.size() ][ i ];
    }
    return res;
}

void solve(){
    int ql, qr; cin >> ql >> qr;
    ll ans = 0;
    if( qr > 0 )
        ans += getCount( qr, true );
    if( qr < -1 )
        ans -= 1LL * ( -qr - 1 ) * 32 - getCount( -qr - 2, true );
    if( ql > 0 )
        ans -= getCount( ql, false );
    if( ql < 0 )
        ans += 1LL * -ql * 32 - getCount( -ql - 1, true );
    cout << ans << "\n";
}

signed main(){
    ios::sync_with_stdio( false );
    // cin.tie( 0 ); cout.tie( 0 );

    #ifdef MULTIPLE_CASES
        int T; cin >> T; while( T-- ) solve();
    #endif

    #ifndef MULTIPLE_CASES
        solve();
    #endif

    return 0;
}