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<bits/stdc++.h>
#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
const int inf=0x3f3f3f3f;
const double eps=1e-6;
const int mod=1000000007;
typedef long long ll;
int modpow(int x,int y,int md=mod){if(y==0)return 1;int ret=modpow(x,y>>1,md);ret=(ll)ret*ret%md;if(y&1)ret=(ll)ret*x%md;return ret;}
int q;
int a,b,c,d,len;
int cnt[1002];
string res;
string baoli1(){
	//a>=b
	for(int i=b-len;i>0;i-=len)cnt[i]++,a--;
	for(int i=0;i<=b&&a;i++){
		if(cnt[i]==len)continue;
		int add=len-cnt[i];
		if(a<add){
			cnt[i]+=a;
			break;
		}
		a-=add;cnt[i]=len;
	}
	res="";
	while(cnt[0]--)res.push_back('A');
	for(int i=1;i<=b;i++){
		res.push_back('B');
		while(cnt[i]--)res.push_back('A');
	}
	res=" "+res;string ret="";
	for(int i=c;i<=d;i++)ret.push_back(res[i]);
	return ret;
}
string baoli2(){
	for(int i=len;i<a;i+=len){
		cnt[i]++;b--;
	}
	for(int i=a;i>=0;i--){
		if(cnt[i]==len)continue;
		int add=len-cnt[i];
		if(b<add){
			cnt[i]+=b;
			break;
		}
		b-=add;cnt[i]=len;
	}
	res="";
	while(cnt[0]--)res.push_back('B');
	for(int i=1;i<=a;i++){
		res.push_back('A');
		while(cnt[i]--)res.push_back('B');
	}
	res=" "+res;string ret="";
	for(int i=c;i<=d;i++)ret.push_back(res[i]);
	return ret;
}
int ok(int x){
	int l=(x)*len+1+max((b-x-1)/len,0ll),r=l+(len-1);
//	cerr<<l<<" "<<r<<" "<<a<<endl;
	if(a<=r)return a-l+1+100000;
	else return 0;
}
string solve1(){
	//a>=b
	int l=-1,r=b;
	while(r-l>1){
		int mid=l+r>>1;
		if(ok(mid))r=mid;
		else l=mid;
	}
//	cerr<<r<<" "<<len+1<<" "<<ok(r)<<endl;
	int size1=(len+1)*r+ok(r)-100000;
	cerr<<size1<<endl;
	string ret="";
	while(c<=d&&c<=size1){
		ret.push_back(c%(len+1)==0?'B':'A');c++;
	}
	if(c>d)return ret;
	int cnt=b-r;
	int rest=cnt%len;if(!rest)rest+=len;
	while(c<=d){
		if(rest==0)ret.push_back('A'),rest=len;
		else ret.push_back('B'),rest--;
		c++;
	}
	return ret;
}
string solve2(){
	swap(a,b);int tmpd=a+b+1-c,tmpc=a+b+1-d;
	c=tmpc;d=tmpd;
	string S=solve1();
	reverse(S.begin(),S.end());
	for(char &_c:S)if(_c=='A')_c='B';else _c='A';
	return S;
}
signed main(){
	srand(time(0));
	/*while(1){
		memset(cnt,0,sizeof cnt);
		cin>>a>>b;if(a==b)continue;
		if(a>b)swap(a,b);
		c=1;d=a+b;len=(a+b)/min(a+1,b+1);
		int ta=a,tb=b,tc=c,td=d,tlen=len;
		string s1=solve2();
		a=ta;b=tb;c=tc;d=td;len=tlen;
		string s2=baoli2();
		cout<<s1<<" "<<s2<<endl;
	}*/
	cin>>q;
	while(q--){
		cin>>a>>b>>c>>d;
		len=(a+b)/min(a+1,b+1);
		memset(cnt,0,sizeof cnt);
		if(a==b){
			for(int i=c;i<=d;i++)if(i&1)cout<<'A';else cout<<'B';
			cout<<endl;continue;
		}
		if(a>=b)cout<<solve1()<<endl;
		else cout<<solve2()<<endl;
//		cerr<<res<<endl;//system("pause");
	}
	return 0;
}