美文网首页线段树
【线段树】CSU_1555_Inversion Sequence

【线段树】CSU_1555_Inversion Sequence

作者: 今天也继续开心涅普涅普 | 来源:发表于2016-11-12 16:22 被阅读0次

1555: Inversion Sequence
Time Limit: 2 Sec Memory Limit: 256 MB
Submit: 478 Solved: 173

Description
For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence which are prior to j and greater to j at the same time. The sequence a1, a2, a3, … , aN is referred to as the inversion sequence of the original sequence (i1, i2, i3, … , iN). For example, sequence 1, 2, 0, 1, 0 is the inversion sequence of sequence 3, 1, 5, 2, 4. Your task is to find a full permutation of 1~N that is an original sequence of a given inversion sequence. If there is no permutation meets the conditions please output “No solution”.

Input
There are several test cases.
Each test case contains 1 positive integers N in the first line.(1 ≤ N ≤ 10000).
Followed in the next line is an inversion sequence a1, a2, a3, … , aN (0 ≤ aj < N)
The input will finish with the end of file.

Output
For each case, please output the permutation of 1~N in one line. If there is no permutation meets the conditions, please output “No solution”.

Sample Input
5
1 2 0 1 0
3
0 0 0
2
1 1

Sample Output
3 1 5 2 4
1 2 3
No solution

题意:
设有一个1~n的全排列,满足给定输入的逆序对数,求这个全排列。
例如:输入5 1 2 0 1 0,即求一个1~5的全排列,满足,1有一个逆序对(即1的前面有且只有1个数字大于它),2有两个逆序对(即2前面有且只有2个数字大于它),3有零个逆序对(3前面没有数字大于它),以此类推。可得3 1 5 2 4。

思路:
模拟这个过程,样例5 1 2 0 1 0中,1前面有1个数字大于它,又因为1是1~n中最小,序列中所有数字都大于它,即1前面只能有一个数字,则1前面留一个空位,即1在从左往右数第2个空位插入,得
_ 1 _ _ _ _
2前面有2个数字大于它,除去1,2在1~n中又最小,同理,2前面留两个空位,在第3个空位插入,得
_ 1 _ 2 _ _
3前面没有数字大于它,同理除去1、2,3是1~n中最小,则3前面留零个空位,在第1个空位插入,得
3 1 _ 2 _
4前面有1个数字大于它,同理,4前面留一个空位,在第2个空位插入,得
3 1 _ 2 4
5前面没有数字大于它,在第1个空位插入,得
3 1 5 2 4
得到结果3 1 5 2 4。
即从1开始到n,每一个数字都去考虑,留几个空位给后面比它大的数字,那么就要实时更新每一段区间空位的数量,使用线段树。

#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 20000 + 5;
int tree[maxn * 4];
int buf[maxn];
int ans[maxn];

// 更新线段树
void Update(int root) {
    tree[root] = tree[root * 2] + tree[root * 2 + 1];
    return;
}

// 递归构造线段树
void Build(int root, int l, int r) {
    if (l == r) {
        tree[root] = 1;
        return;
    }
    int mid = (l + r) / 2;
    Build(root * 2, l, mid);
    Build(root * 2 + 1, mid + 1, r);
    Update(root);
    return;
}

// 找到位置插入数字
int Insert(int val, int root, int l, int r) {
    if (l == r) {
        tree[root] = 0;
        return l;
    }
    int mid = (l + r) / 2;
    int ret;
    if (tree[root << 1] >= val)
        ret = Insert(val, root * 2, l, mid);
    else
        ret = Insert(val - tree[root * 2], root * 2 + 1, mid + 1, r);
    Update(root);
    return ret;
}

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        // memset(tree, 0, sizeof(tree));
        Build(1, 1, n);
        bool noSolution = false;
        for (int i = 1; i <= n; ++i)
            scanf("%d", buf + i);
        for (int i = 1; i <= n; ++i) {
            // 任何时候空位数小于所给逆序对数,即当前数字没位置插入,则无解
            if (tree[1] <= buf[i]) {
                noSolution = true;
                break;
            }
            // 在第buf[i]+1个位置插入i
            ans[Insert(buf[i] + 1, 1, 1, n)] = i;
        }
        if (noSolution)
            printf("No solution\n");
        else {
            for (int i = 1; i < n; ++i)
                printf("%d ", ans[i]); 
            printf("%d\n", ans[n]);
        }
    }
    return 0;
}

相关文章

  • 【线段树】CSU_1555_Inversion Sequence

    1555: Inversion SequenceTime Limit: 2 Sec Memory Limit: ...

  • 算法模板(七) 线段树

    线段树单点操作 线段树区间操作

  • 数据结构-线段树

    实现一个线段树 下面实现的线段树,有三个功能: 把数组构建成一颗线段树 线段树的修改 线段树的查询 303号问题 ...

  • 线段树系列之——区间更新

    第三篇线段树了——重点不在于解决题目,通过题目理解线段树才是重点 前面写了一篇关于线段树的单点更新,线段树的单点更...

  • 线段树模板

    线段树 线段树基本概念 概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组)...

  • 线段树专题整理

    待更新 线段树讲解(未读)线段树模板(未读) 模板 求区间总和 A - 敌兵布阵 HDU - 1166 题意 线段...

  • 线段树 02 构建线段树

    构建线段树 线段树的每个节点除了天然的对应一段长度外,不一定赋予其上的意义就是区间元素的和,所以两个节点向上汇聚成...

  • 线段树(区间树)

    线段树:线段树是一种二叉树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。线段树适用于不变...

  • 线段树

    专题 B线段树求逆序对 C[] D 区间不同值求和

  • 线段树

    [toc] 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn。(2).线段树算...

网友评论

    本文标题:【线段树】CSU_1555_Inversion Sequence

    本文链接:https://www.haomeiwen.com/subject/nyeqpttx.html