J
题意:给你一个hash表,让你给出一个字典序最小的输入。
思路:按数字大小从小到大插入,用链表和bit维护过程。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 2e5 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, tot, all, ans[N], a[N], L[N], R[N]; vector<pii> vec; struct node { int nx, pre, val; } b[N]; struct BIT { int a[N]; void init(int n) { for(int i = 0; i <= n; i++) a[i] = 0; } void modify(int x, int v) { for(int i = x; i <= n; i += i & -i) a[i] += v; } int sum(int x) { int ans = 0; for(int i = x; i; i -= i & -i) ans += a[i]; return ans; } } bit; void del(int u) { int to = b[u].nx; int from = b[u].pre; b[from].nx = b[u].nx; b[to].pre = b[u].pre; } bool is(int l, int r) { if(l == r) return true; if(l < r) return bit.sum(r) - bit.sum(l - 1) == (r - l); return bit.sum(r) + bit.sum(n) - bit.sum(l - 1) == (r + n - l); } void check(int u, int fa) { if(u == fa || b[u].val == -1 || !is(L[u], R[u])) return; int to = b[u].nx; ans[tot++] = b[u].val; bit.modify(u, 1); del(u); check(to, u); } int main() { int T; scanf("%d", &T); while(T--) { tot = 0; all = 0; vec.clear(); scanf("%d", &n); bit.init(n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i].val = -1; b[i].nx = (i + 1 - 1) % n + 1; b[i].pre = (i - 1 - 1 + n) % n + 1; if(a[i] != -1) { L[i] = a[i] % n + 1; R[i] = i; vec.push_back(mk(a[i], i)); } } sort(vec.begin(), vec.end()); for(int i = 0; i < vec.size(); i++) { int l = vec[i].fi % n + 1, r = vec[i].se; b[r].val = vec[i].fi; if(is(l, r)) { check(r, -1); } } if(tot != vec.size()) { puts("-1"); } else { if(tot == 0) { puts(""); } else { printf("%d", ans[0]); for(int i = 1; i < tot; i++) printf(" %d", ans[i]); puts(""); } } } return 0; } /* 1 10 8 10 -1 -1 34 75 86 55 88 18 */