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.
Stop caring about the actual values in . Only comparisons like matter, so the real object you need is an order of indices from smallest to largest .
Process indices from right to left. When you handle , all possible dominators of are already in the suffix, and future insertions of smaller indices can never change the answer for an already processed index.
For a fixed , let be the number of indices with . If , you are dead immediately. Otherwise needs exactly of those relevant indices to be before it in the -order.
Look at the current suffix order and ignore every index with ; they do not affect at all. The remaining relevant indices split the line into slots, and inserting into slot number makes exactly relevant indices appear before it.
Maintain ord = processed indices in increasing . For , collect positions in ord with larger than . If there are only of them and , output -1. Otherwise let i` right after the -th such position (or at the front if ). Finally set .
The actual values inside do not matter. Only comparisons like matter.
So forget the numbers for a second and build an order ord of indices from smallest to largest .
Then dominates exactly when , , and is placed after in ord.
For each , let be the number of indices with . If , the answer is impossible. There simply are not enough candidates.
When you place index , every possible dominator of is already in the suffix . Even better, once some index is already placed, it is frozen forever: later we only insert indices smaller than , and such indices can never dominate because domination needs .
So processing is the obvious greedy.
Suppose we already built ord for the suffix.
Look only at the processed indices with . In their current order, call them
Index wants exactly of them after it, so it wants exactly
of them before it.
Now comes the whole trick: these relevant indices create exactly slots:
If you insert into slot number , then exactly relevant indices are before it. So every value is achievable.
That means the condition that is at most is not only necessary. It is also sufficient. Yep, the global consistency nightmare evaporates into one boring local bound.
Maintain ord = processed indices in increasing .
For :
ord whose is larger than .-1.
and insert right after the -th collected position. If , insert at the front.
Any slot with the right count works; this is just a clean canonical choice.
After all insertions, assign
Since ord is from smallest to largest , this is a valid permutation.
Use induction on decreasing .
Invariant after processing the suffix :
ord is the correct increasing- order of that suffix;Base case: the empty suffix. Trivially true.
Induction step: for the current index , the only possible dominators are already processed, and among them only the ones with matter. There are exactly of them. By the slot lemma, we can place so that exactly of them are before it, hence exactly of them are after it. So becomes correct.
Previously processed indices stay correct, because the new index is smaller than all of them, and a dominator must have larger index. So no old answer changes.
Thus the invariant survives, and when the process ends, every index is correct.
If the algorithm rejects, it found some with , which is obviously impossible. So the algorithm is correct in both directions.
For each , we scan the current ord and do one vector insertion.
That is
time and memory.
Since the total over all test cases is at most , this passes comfortably. Dragging heavier machinery here would just be algorithm cosplay.
#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 t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> p(n + 1), d(n + 1);
for (int i = 1; i <= n; ++i) cin >> p[i];
for (int i = 1; i <= n; ++i) cin >> d[i];
// ord stores processed indices from smaller q to larger q
vector<int> ord;
ord.reserve(n);
bool ok = true;
for (int i = n; i >= 1; --i) {
// positions of suffix indices that are relevant for i
vector<int> bigger_pos;
bigger_pos.reserve(ord.size());
for (int pos = 0; pos < (int)ord.size(); ++pos) {
if (p[ord[pos]] > p[i]) bigger_pos.push_back(pos);
}
int c = (int)bigger_pos.size();
if (d[i] > c) {
ok = false;
break;
}
int before = c - d[i];
int insert_pos = (before == 0 ? 0 : bigger_pos[before - 1] + 1);
ord.insert(ord.begin() + insert_pos, i);
}
if (!ok) {
cout << -1 << char(10);
continue;
}
vector<int> q(n + 1);
for (int pos = 0; pos < n; ++pos) {
q[ord[pos]] = pos + 1;
}
for (int i = 1; i <= n; ++i) {
if (i > 1) cout << ' ';
cout << q[i];
}
cout << char(10);
}
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 t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> p(n + 1), d(n + 1);
for (int i = 1; i <= n; ++i) cin >> p[i];
for (int i = 1; i <= n; ++i) cin >> d[i];
// ord stores processed indices from smaller q to larger q
vector<int> ord;
ord.reserve(n);
bool ok = true;
for (int i = n; i >= 1; --i) {
// positions of suffix indices that are relevant for i
vector<int> bigger_pos;
bigger_pos.reserve(ord.size());
for (int pos = 0; pos < (int)ord.size(); ++pos) {
if (p[ord[pos]] > p[i]) bigger_pos.push_back(pos);
}
int c = (int)bigger_pos.size();
if (d[i] > c) {
ok = false;
break;
}
int before = c - d[i];
int insert_pos = (before == 0 ? 0 : bigger_pos[before - 1] + 1);
ord.insert(ord.begin() + insert_pos, i);
}
if (!ok) {
cout << -1 << char(10);
continue;
}
vector<int> q(n + 1);
for (int pos = 0; pos < n; ++pos) {
q[ord[pos]] = pos + 1;
}
for (int i = 1; i <= n; ++i) {
if (i > 1) cout << ' ';
cout << q[i];
}
cout << char(10);
}
return 0;
}