uva 11525 - Permutation(线段树)

来源:互联网 发布:剑灵 职业 知乎 编辑:程序博客网 时间:2024/06/09 16:19

题目链接:uva 11525 - Permutation

题目大意:给定n和k,n给定的方式为k个si,根据公式计算出n,求一个由1~k组成的长度为k的序列的第n个排序

解题思路:根据公式的性质,等于对于每个位置找当前状态下第si小的数。线段树子节点均为1,维护和,查询时传入参数查找即可。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 50005;#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)+1)struct Node {    int l, r, val;    void set (int l, int r, int val) {        this->l = l;        this->r = r;        this->val = val;    }}node[maxn * 4];void pushup(int u) {    node[u].set(node[lson(u)].l, node[rson(u)].r, node[lson(u)].val + node[rson(u)].val);}void build_segTree (int u, int l, int r) {    if (l == r) {        node[u].set(l, r, 1);        return ;    }    int mid = (l + r) / 2;    build_segTree(lson(u), l, mid);    build_segTree(rson(u), mid + 1, r);    pushup(u);}int query_segTree (int u, int val) {    if (node[u].l == node[u].r && val == 1)        return node[u].l;    if (val > node[lson(u)].val)        return query_segTree(rson(u), val - node[lson(u)].val);    else        return query_segTree(lson(u), val);}void insert_segTree (int u, int x, int val) {    if (node[u].l == x && node[u].r == x) {        node[u].val += val;        return ;    }    int mid = (node[u].l + node[u].r) / 2;    if (x <= mid)        insert_segTree(lson(u), x, val);    else        insert_segTree(rson(u), x, val);    pushup(u);}int main () {    int cas;    scanf("%d", &cas);    while (cas--) {        int n, x;        scanf("%d", &n);        build_segTree(1, 1, n);        for (int i = 1; i <= n; i++) {            scanf("%d", &x);            x = query_segTree(1, x+1);            insert_segTree(1, x, -1);            printf("%d%c", x, i == n ? '\n' : ' ');        }    }    return 0;}
1 0