B - Ultraman vs. Aodzilla and Bodzilla(贪心)

显然先将其中一个怪杀死是更优的。

然后可以分类讨论先杀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;
}