• csu 1555(线段树经典插队模型-根据逆序数还原序列)


    1555: Inversion Sequence

    Time Limit: 2 Sec  Memory Limit: 256 MB
    Submit: 469  Solved: 167
    [Submit][Status][Web Board]

    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

    HINT

    题意:知道1-n 所有数的逆序数,要求还原序列.例如 : 1 2 0 1 0 ,那么 1 前面有 1个数大于1,2前面有 2个数大于2,依次类推.

    不会的可以去做一下poj 2828 ,经典模型了,在线段树更新的时候就能够完成所有操作了.对于某个数 i ,它前面的数数量为 k ,那么它就在线段树第 k+1 个空位上.假设当前的线段树能够插的空位数量不足 k+1 ,那么就无解了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    #define N 10005
    int a[N],ans[N];
    
    int tree[N<<2];
    void pushup(int idx){
        tree[idx] = tree[idx<<1]+tree[idx<<1|1];
    }
    void build(int l,int r,int idx){
        if(l==r){
            tree[idx] = 1;
            return;
        }
        int mid = (l+r)>>1;
        build(l,mid,idx<<1);
        build(mid+1,r,idx<<1|1);
        pushup(idx);
    }
    void update(int value,int i,int l,int r,int idx){
        if(l==r){
            ans[l] = i;
            tree[idx] = 0;
            return;
        }
        int mid = (l+r)>>1;
        if(tree[idx<<1]>=value) update(value,i,l,mid,idx<<1); ///插向左子树
        else update(value-tree[idx<<1],i,mid+1,r,idx<<1|1);
        pushup(idx);
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF){
            memset(tree,0,sizeof(tree));
            memset(ans,0,sizeof(ans));
            build(1,n,1);
            bool flag = false;
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                a[i]++;  ///它前面的空格数为a[i] ,自然它应该在第 a[i]+1 个空格位置
                if(tree[1]<a[i]) flag = true;
                if(!flag)
                update(a[i],i,1,n,1);
            }
            if(flag){
                printf("No solution
    ");
                continue;
            }
            for(int i=1;i<n;i++){
                printf("%d ",ans[i]);
            }
            printf("%d
    ",ans[n]);
        }
        return 0;
    }
  • 相关阅读:
    Electron dialog 对话框的使用
    Electron BrowserView 的使用
    自动化测试相关
    使用chrome开发者工具中的performance面板解决性能瓶颈
    Electron window.open 函数 和 Browser-window-proxy 对象的使用
    Electron webview 标签
    Electron File对象
    Electron 进程
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5793498.html
Copyright © 2020-2023  润新知