牛客多校4

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
*/
View Code

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9385892.html
今日推荐