zoukankan      html  css  js  c++  java
  • HDU 5592 ZYB's Premutation(BestCoder Round #65 C)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5592

    ZYB's Premutation

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 483    Accepted Submission(s): 236


    Problem Description
    ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to
    restore the premutation.

    Pair (i,j)(i<j) is considered as a reverse log if Ai>Aj is matched.
     
    Input
    In the first line there is the number of testcases T.

    For each teatcase:

    In the first line there is one number N.

    In the next line there are N numbers Ai,describe the number of the reverse logs of each prefix,

    The input is correct.

    1T5,1N50000
     
    Output
    For each testcase,print the ans.
     
    Sample Input
    1 3 0 1 2
     
    Sample Output
    3 1 2
     
    Source
     
    题意:输入t,代表t组测试样例,每组样例一个n,代表有n个数,输入n个数a[i],表示从1到i有a[i]个逆序数对,求数字1-n的摆放顺序。
     
    分析:线段树维护。
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    
    int num[50005];
    int ans[50005];
    int aa[50005];
    struct Tree
    {
        int x, sum;
    }a[200005];
    
    void Build(int rt, int l, int r, int n)
    {
        if(l == r)
        {
            a[rt].x = l;
            a[rt].sum = 1;
            return ;
        }
        Build(rt*2, l, (l+r)/2, n);
        Build(rt*2+1, (l+r)/2+1, r, n);
        a[rt].sum = a[rt*2].sum + a[rt*2+1].sum;
    }
    
    int Querry(int rt, int l, int r, int num)
    {
        int ans;
        if(l == r)
        {
            a[rt].sum--;
            return a[rt].x;
        }
        if(num > a[rt*2].sum)
            ans = Querry(rt*2+1, (l+r)/2+1, r, num - a[rt*2].sum);
        else
            ans = Querry(rt*2, l, (l+r)/2, num);
        
        a[rt].sum--;
        return ans;
    } 
    
    int main()
    {
        int t, n;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d", &n);
            aa[0] = 0;
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &aa[i]);
                num[i] = aa[i] - aa[i-1];//num[i]保存i前面有多少个比ans[i]大
            }
            Build(1, 1, n, n);
            for(int i=n; i>=1; i++)
            {
                ans[i] = Querry(1, 1, n, num[i]+1);
            }
            for(int i=1;i<=n;i++)
            {
                printf("%d%c",ans[i],i==n?'
    ':' ');
            }
            
        }
        
        return 0;
    }
  • 相关阅读:
    Git合并
    Git对象
    Git储藏和引用日志
    小小c#算法题 4 子数组最大和
    小小c#算法题 2 求素数
    小小c#算法题 5 插入排序
    小小c#算法题 1 找出数组中满足条件的两个数
    [转] WPF – Editing Mode with Save and Cancel Capability
    小小c#算法题 0 单循环冒泡排序
    小小c#算法题 3 字符串语句反转
  • 原文地址:https://www.cnblogs.com/mengzhong/p/5026420.html
Copyright © 2011-2022 走看看