0w1

CFR Educational 6 D. Professor GukiZ and Two Arrays ( lower_bound )

Problem - D - Codeforces
We can simply brute force for 0 and 1 swap, so let's think about 2 swaps. When 2 swaps are committed, and given that asum is the sum for all elements in a, same for bsum, swapping ( i, j ) in A with ( x, y ) in B, and without losing generality let asum ≥ bsum, we will have the new final cost as
new_cost = [ asum - bsum + 2*( b[x] + b[y] ) ] - 2*( a[i] + a[j] )
If ( x, y ) is fixed, we will simply have to find ( i, j ) that produces 2*( a[i] + a[j] ) nearest to the value in the angled bracket. This can be achieved easily with preprocessing and set::lower_bound.

typedef ll T_triplet;
struct triplet{
    T_triplet first, second, third;
    triplet(){}
    triplet( T_triplet _f, T_triplet _s, T_triplet _t ){
        first = _f, second = _s, third = _t;
    }
    bool operator < ( const triplet &oth ) const{
        if( first != oth.first ) return first < oth.first;
        if( second != oth.second ) return second < oth.second;
        return third < oth.third;
    }
};

const ll LINF = 1LL << 60;

void solve(){
    int N; cin >> N;
    vi A( N );
    for( int i = 0; i < N; ++i )
        cin >> A[ i ];

    int M; cin >> M;
    vi B( M );
    for( int i = 0; i < M; ++i )
        cin >> B[ i ];

    ll asum = 0, bsum = 0;
    for( int i = 0; i < N; ++i ) asum += A[ i ];
    for( int i = 0; i < M; ++i ) bsum += B[ i ];
    ll min_cost = abs( asum - bsum );

    bool is_swapped = false;
    if( not ( asum >= bsum ) ) // to make things a little easier( ? )
        is_swapped = true,
        swap( N, M ),
        swap( asum, bsum ),
        swap( A, B );

    vp pair2swap;

    for( int i = 0; i < N; ++i )
        for( int j = 0; j < M; ++j ){
            ll nasum = asum - A[ i ] + B[ j ];
            ll nbsum = bsum - B[ j ] + A[ i ];
            if( abs( nasum - nbsum ) < min_cost )
                min_cost = abs( nasum - nbsum ),
                pair2swap = { pii( i, j ) };
        }

    set< triplet > ast;
    for( int i = 0; i < N; ++i )
        for( int j = i + 1; j < N; ++j )
            ast.insert( triplet( 2LL * ( A[ i ] + A[ j ] ), i, j ) );
    for( int i = 0; i < M; ++i )
        for( int j = i + 1; j < M; ++j ){
            if( ast.empty() ) break;
            ll z = asum - bsum + 2LL * ( B[ i ] + B[ j ] );
            auto it = ast.lower_bound( triplet( z, -1, -1 ) );
            if( it == ast.end() ){
                --it;
                ll score = abs( z - it->first );
                if( score < min_cost )
                    min_cost = score,
                    pair2swap = { pii( it->second, i ), pii( it->third, j ) };
            } else{
                ll score = abs( z - it->first );
                if( score < min_cost )
                    min_cost = score,
                    pair2swap = { pii( it->second, i ), pii( it->third, j ) };
                if( it != ast.begin() ){
                    --it;
                    score = abs( z - it->first );
                    if( score < min_cost )
                        min_cost = score,
                        pair2swap = { pii( it->second, i ), pii( it->third, j ) };
                }
            }
        }

    cout << min_cost << "\n";
    cout << pair2swap.size() << "\n";
    for( int i = 0; i < pair2swap.size(); ++i ){
        if( is_swapped )
            cout << pair2swap[ i ].second + 1 << " " << pair2swap[ i ].first + 1 << "\n";
        else
            cout << pair2swap[ i ].first + 1 << " " << pair2swap[ i ].second + 1 << "\n";
    }
}