显然先将其中一个怪杀死是更优的。
然后可以分类讨论先杀A还是B
1.杀A。
因为要字典序小,所以先预处理出杀死A和杀死B以及杀死A+B对应的时间。
然后看总伤害减去杀A的伤害看是否能杀死B。
如果能就是连续A+连续的B。
否则A就存在多的伤害可以去杀B,要字典序最小,尽可能靠后。
显然刚好 i = i= i=多余伤害时候最优。
2.杀B。
考虑杀B多的伤害去放在前缀杀A,如果后缀+前缀的A能杀死A
则答案就是AAA…BBBB…AAA
否则考虑将前缀的A后移。满足$rest-i>i || rest==i $ 就一直放A。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 7;
ll p[N];
int main() {
for(int i = 1; i < N; ++i) p[i] = p[i - 1] + i;
int t;
ll a1, a2, h1, h2;
scanf("%d", &t);
while(t--) {
scanf("%lld%lld%lld%lld", &h1, &h2, &a1, &a2);
string s1 = "", s2 = "";
ll ans1 = 0, ans2 = 0;
ll all = lower_bound(p + 1, p + N, h1 + h2) - p;///总
ll a = lower_bound(p + 1, p + N, h1) - p; ///A
ll b = lower_bound(p + 1, p + N, h2) - p; ///B
///A
ll now = p[all] - p[a];
ans1 = a * a1 + all * a2;
if(now >= h2) {
string tmp1(a, 'A'), tmp2(all - a, 'B');
s1 = tmp1 + tmp2;
}
else {
ll lost = p[a] - h1;
string tmp1(lost - 1, 'A'), tmp2(a - lost, 'A'), tmp3(all - a, 'B');
s1 = tmp1 + "B" + tmp2 + tmp3;
}
///B
now = p[all] - p[b];
ll lost = p[b] - h2, it;
ans2 = b * a2 + all * a1;
it = upper_bound(p + 1, p + N, lost) - p - 1;
ll sum = p[it] + now;
if(sum >= h1) {
string tmp1(it, 'A'), tmp2(b - it, 'B'), tmp3(all - b, 'A');
s2 = tmp1 + tmp2 + tmp3;
}
else {
ll left = h1 - now;
for(int i = 1; i <= b; ++i) {
if(left >= 2 * i + 1 || left == i) {
left -= i;
s2 += "A";
}
else s2 += "B";
}
string tmp(all - b, 'A');
s2 += tmp;
}
if(ans1 < ans2) cout<<ans1<<' '<<s1<<'\n';
else if(ans1 > ans2) cout<<ans2<<' '<<s2<<'\n';
else {
if(s1 < s2) cout<<ans1<<' '<<s1<<'\n';
else cout<<ans2<<' '<<s2<<'\n';
}
}
return 0;
}