Problem:
Score : 1100 points

Problem Statement

Let f(A, B), where A and B are positive integers, be the string satisfying the following conditions:

f(A, B) has length A + B;

f(A, B) contains exactly A letters A and exactly B letters B;

The length of the longest substring of f(A, B) consisting of equal letters (ex., AAAAA or BBBB) is as small as possible under the conditions above;

f(A, B) is the lexicographically smallest string satisfying the conditions above.

For example, f(2, 3) = BABAB, and f(6, 4) = AABAABAABB.

Answer Q queries: find the substring of f(A_i, B_i) from position C_i to position D_i (1-based).

Constraints

1 \leq Q \leq 10^3

1 \leq A_i, B_i \leq 5 \times 10^8

1 \leq C_i \leq D_i \leq A_i + B_i

D_i - C_i + 1 \leq 100

All input values are integers.

Partial Score

500 points will be awarded for passing the testset satisfying 1 \leq A_i, B_i \leq 10^3.

Input

Input is given from Standard Input in the following format:

Q
A_1 B_1 C_1 D_1
A_2 B_2 C_2 D_2
:
A_Q B_Q C_Q D_Q

Output

For each query i in order of input, print a line containing the substring of f(A_i, B_i) from position C_i to position D_i (1-based).

Sample Input 1

5
2 3 1 5
6 4 1 10
2 3 4 4
6 4 3 7
8 10 5 8

Sample Output 1

BABAB
AABAABAABB
A
BAABA
ABAB

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <functional>
#include <algorithm>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <vector>
#include <array>
#include <tuple>
#include <utility>
#include <numeric>
#include <iomanip>
#include <cctype>
#include <cmath>
#include <assert.h>
#include <cstdlib>
#include <list>
using namespace std;

#define repeat(i, x) for (long long i = 0; (i) < (long long)(x); (i)++)
#define rrepeat(i, x) for (long long i = (long long)((x) - 1); (i) >= 0; (i)--)
#define traverse(it, ctn) for (auto it = (ctn).begin(); (it) != (ctn).end(); (it)++)
#define rtraverse(it, ctn) for (auto it = (ctn).rbegin(); (it) != (ctn).rend(); (it)++)
#define enumerate(i, a, b) for (long long i = (long long)(a); (i) < (long long)(b); (i)++)

template<typename T> void chmax(T& a1, T a2) { a1 = std::max(a1, a2); }
template<typename T> void chmin(T& a1, T a2) { a1 = std::min(a1, a2); }

template<typename T1, typename T2> ostream& operator<<(ostream& os, const pair<T1, T2>& p) { return os << "(" << p.first << ", " << p.second << ")"; }
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) { os << "["; for (int i = 0; i < v.size(); i++) os << (i == 0 ? "" : ", ") << v[i]; os << "]"; return os; }
template<typename T1, typename T2> ostream& operator << (ostream& os, map<T1, T2>& mp) { os << "{"; for (auto it = mp.begin(); it != mp.end(); it++) { os << "(" << it->first << ": " << it->second << ")"; it++; if(it != mp.end()) os << ", "; it--; } os << "}"; return os; }
template<typename T> ostream& operator << (ostream& os, set<T>& st) { os << "{"; for (auto it = st.begin(); it != st.end(); it++) { os << *it; ++it; if(it != st.end()) os << ", "; it--; } os << "}"; return os; }

using int64 = long long;
using Graph = std::vector<std::vector<int>>;

bool is_valid(int64 A, int64 B, int64 x) {
    int64 a_num = (A + x - 1) / x;
    int64 b_num = (B + x - 1) / x;

    for (int a = a_num; a <= A; a++) {
        if (a - 1 <= B and B <= (a + 1) * x) return true;
    }
    for (int b = b_num; b <= B; b++) {
        if (b - 1 <= A and A <= (b + 1) * x) return true;
    }
    return false;
}

bool check(int64 A, int64 B, int64 x, int start) {
    int64 a_num = (A + x - 1) / x;
    int64 b_num = (B + x - 1) / x;
    // aが先頭
    if (start == 0) {
        for (int b = b_num; b <= B; b++) {
            if (b <= A and A <= (b + 1) * x) return true;
        }
    } else {
    // bが先頭
        for (int a = a_num; a <= A; a++) {
            if (a <= B and B <= (a + 1) * x) return true;
        }
    }
    return false;
}

string build(int64 A, int64 B, int64 x) {
    string res = "";
    int prev = -1;
    for (int i = min(A, x); i >= 1; i--) {
        if (check(A - i, B, x, 1)) {
            prev = 0;
            for (int j = 0; j < i; j++) {
                res.push_back('A');
            }
            A -= i;
            break;
        }
    }

    if (prev == -1) {
        for (int i = 1; i <= min(B, x); i++) {
            if (check(A, B - i, x, 0)) {
                prev = 1;
                for (int j = 0; j < i; j++) {
                    res.push_back('B');
                }
                B -= i;
                break;
            }
        }
    }
    while (A > 0 or B > 0) {
        // cerr << "ffffffffffff" << endl;
        // cerr << "A: " << A << " B: " << B << " prev: " << prev << endl;
        /*
        cerr << res << endl;
        cerr << x << endl;
        */
        if (prev == 0) {
            for (int i = 1; i <= min(B, x); i++) {
                if (check(A, B - i, x, 0)) {
                    // cerr << "A: " << A << " B-i: " << B - i << " prev: " << prev << endl;
                    /*
                    if (A == 7 and B == 9) {
                        cerr << "foo" << endl;
                    }
                    */
                    prev = 1;
                    for (int j = 0; j < i; j++) {
                        res.push_back('B');
                    }
                    B -= i;
                    break;
                }
            }
        } else {
            for (int i = min(A, x); i >= 1; i--) {
                if (check(A - i, B, x, 1)) {
                    /*
                    if (A == 7 and B == 9) {
                        cerr << "foo" << endl;
                    }
                    */
                    prev = 0;
                    for (int j = 0; j < i; j++) {
                        res.push_back('A');
                    }
                    A -= i;
                    break;
                }
            }
        }
    }

    return res;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int Q;
    cin >> Q;

    repeat (i, Q) {
        int64 A, B, C, D;
        cin >> A >> B >> C >> D;
        C--;

        if (A > 1000 or B > 1000) return 0;

        int64 ng = 0,
              ok = (1LL << 40);
        while (ok - ng > 1) {
            int64 mid = (ok + ng) / 2;
            if (is_valid(A, B, mid)) ok = mid; 
            else ng = mid;
        }
        /*
        cerr << "ok: " << ok << endl;
        cerr << "A: " << A << " B: " << B << endl;
        */

        string f = build(A, B, ok);
        // cerr << "ans: " << f.substr(C, (D - C)) << endl;
        cout << f.substr(C, (D - C)) << endl;
        // cerr << check(6, 9, 2, 1) << endl;
    }

    return 0;
}