Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
When two elves fight, the weaker one always dies. Its health is at most its own attack value, and it loses the stronger elf's attack value.
Stopping is the annoying part. If at least two elves are alive at the end, then every survivor must have attacked already.
Sort elves by attack. An increasing chain kills everyone in that chain except .
For , each survivor needs a distinct weaker target for its one attack. So you need at least dead elves: .
For , only the maximum elf is hard to kill. It can die iff the sum of all other attacks is at least its attack. Then damage it carefully and save one remaining elf for the final hit.
Two things matter here: who dies, and who has already attacked. The health values look scary, but the core is pretty clean.
The basic fight fact
Sort the elves by attack:
In any fight between two living elves, the weaker elf always dies. Why? Its current health is never more than its original value, and it loses the stronger elf's attack value, which is larger.
The stronger elf may survive or may also die if it was already damaged. But if it is fresh enough and only loses a weaker attack value, it survives.
So an attack
kills and leaves alive. Therefore an increasing chain
kills the whole chain except . This is the main hammer.
The stopping rule
The process stops only when there is no living elf that has not attacked and has another living elf to target.
So:
That last bullet is the classic trap. Leaving two untouched survivors is not a solution. The spell keeps going. Brutal, but fair.
Impossible:
Initially , all elves are alive, and nobody has attacked, so the process cannot stop immediately.
At least one attack must happen. The first attack kills the weaker of the two elves, so ending with all elves alive is impossible.
Case
Always possible.
Just chain through all elves in increasing attack order:
Every attacker dies, and the next elf survives. In the end only is alive. A single survivor does not need to have attacked, because there is nobody else to attack.
Case
Every final survivor must have attacked.
A survivor cannot attack a stronger survivor, because then it would die. It also cannot attack a weaker survivor, because then the weaker survivor would die. So each survivor must spend its attack on some weaker elf that is supposed to die.
Those targets must be distinct, because a target dies immediately after being hit by a stronger survivor. Therefore we need at least dead elves:
Equivalently:
This condition is also enough.
Take the largest elves as survivors. The other elves are doomed. Since , split the doomed elves into nonempty consecutive groups in sorted order.
For one group
assigned to survivor , do the chain inside the group:
Now only remains alive from that group. Then do
Since is one of the largest elves, it is stronger than every doomed elf. So dies, survives, and has attacked.
Do this for every group. Exactly the chosen survivors remain, and all of them have attacked, so the process is forced to stop.
Case
Now everyone must die. Let be the maximum elf, with attack .
The maximum elf can only lose health by interacting with weaker elves. Each weaker elf can damage it at most once, because that weaker elf dies immediately in such an interaction. So if
then the maximum elf can never die. Impossible.
Now suppose
We construct a full wipe.
First make the maximum attack the second maximum:
The second maximum dies, and remains alive with health
Call this remaining health need.
Now look at the remaining elves . While the largest remaining elf has attack less than need, make that elf attack . It dies, and need decreases by its attack. We only do this while its attack is strictly smaller than need, so stays alive.
Why can this loop not run out of elves? Initially the total attack of these remaining elves is at least need, because the total attack of all non-maximum elves is at least . Every time we use an elf against , both the remaining total and need decrease by the same amount. So eventually some remaining elf has attack at least need.
Once that happens, chain all still-unused remaining elves in increasing order, leaving the largest of them alive and not having attacked. Then this last elf attacks .
Its attack is at least need, so dies. It also dies from recoil because is stronger. Now nobody is alive. Merry chaos.
Complexity
Sorting costs per test case. The construction prints at most attacks, and the total over all tests is bounded by .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int tc;
cin >> tc;
while (tc--) {
int n, m;
cin >> n >> m;
vector<pair<ll, int>> p(n);
for (int i = 0; i < n; i++) {
cin >> p[i].first;
p[i].second = i + 1;
}
sort(p.begin(), p.end());
vector<pair<int, int>> ans;
if (m == n) {
cout << -1 << '\n';
continue;
}
if (m == 0) {
ll mx = p.back().first;
ll sumSmall = 0;
for (int i = 0; i + 1 < n; i++) sumSmall += p[i].first;
if (sumSmall < mx) {
cout << -1 << '\n';
continue;
}
ans.push_back({p[n - 1].second, p[n - 2].second});
ll need = mx - p[n - 2].first;
vector<int> rem;
for (int i = 0; i <= n - 3; i++) rem.push_back(i);
while (need > p[rem.back()].first) {
int id = rem.back();
rem.pop_back();
ans.push_back({p[id].second, p[n - 1].second});
need -= p[id].first;
}
for (int i = 0; i + 1 < (int)rem.size(); i++) {
ans.push_back({p[rem[i]].second, p[rem[i + 1]].second});
}
ans.push_back({p[rem.back()].second, p[n - 1].second});
} else if (m == 1) {
for (int i = 0; i + 1 < n; i++) {
ans.push_back({p[i].second, p[i + 1].second});
}
} else {
if (2 * m > n) {
cout << -1 << '\n';
continue;
}
int doomed = n - m;
int cur = 0;
for (int g = 0; g < m; g++) {
int groupsLeft = m - g;
int remaining = doomed - cur;
int len = remaining - (groupsLeft - 1);
int l = cur;
int r = cur + len - 1;
for (int i = l; i < r; i++) {
ans.push_back({p[i].second, p[i + 1].second});
}
ans.push_back({p[doomed + g].second, p[r].second});
cur = r + 1;
}
}
cout << ans.size() << '\n';
for (auto [x, y] : ans) {
cout << x << ' ' << y << '\n';
}
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int tc;
cin >> tc;
while (tc--) {
int n, m;
cin >> n >> m;
vector<pair<ll, int>> p(n);
for (int i = 0; i < n; i++) {
cin >> p[i].first;
p[i].second = i + 1;
}
sort(p.begin(), p.end());
vector<pair<int, int>> ans;
if (m == n) {
cout << -1 << '\n';
continue;
}
if (m == 0) {
ll mx = p.back().first;
ll sumSmall = 0;
for (int i = 0; i + 1 < n; i++) sumSmall += p[i].first;
if (sumSmall < mx) {
cout << -1 << '\n';
continue;
}
ans.push_back({p[n - 1].second, p[n - 2].second});
ll need = mx - p[n - 2].first;
vector<int> rem;
for (int i = 0; i <= n - 3; i++) rem.push_back(i);
while (need > p[rem.back()].first) {
int id = rem.back();
rem.pop_back();
ans.push_back({p[id].second, p[n - 1].second});
need -= p[id].first;
}
for (int i = 0; i + 1 < (int)rem.size(); i++) {
ans.push_back({p[rem[i]].second, p[rem[i + 1]].second});
}
ans.push_back({p[rem.back()].second, p[n - 1].second});
} else if (m == 1) {
for (int i = 0; i + 1 < n; i++) {
ans.push_back({p[i].second, p[i + 1].second});
}
} else {
if (2 * m > n) {
cout << -1 << '\n';
continue;
}
int doomed = n - m;
int cur = 0;
for (int g = 0; g < m; g++) {
int groupsLeft = m - g;
int remaining = doomed - cur;
int len = remaining - (groupsLeft - 1);
int l = cur;
int r = cur + len - 1;
for (int i = l; i < r; i++) {
ans.push_back({p[i].second, p[i + 1].second});
}
ans.push_back({p[doomed + g].second, p[r].second});
cur = r + 1;
}
}
cout << ans.size() << '\n';
for (auto [x, y] : ans) {
cout << x << ' ' << y << '\n';
}
}
return 0;
}