zoukankan      html  css  js  c++  java
  • hdu 5592 ZYB's Premutation (线段树+二分查找)

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

    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

       思路:对于每个位置i,a[i]-a[i-1]就是它前面比它大的数,这样就能知道它是从1到i中第几大的数了。从第n个位开始找,每找到一个数给它标记掉。在线段树中存没标记的数,用二分查找数的大小。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 struct st
     6 {
     7     int l,r;
     8     int sum;
     9 };
    10 st tree[500005];
    11 void build(int l,int r,int p)
    12 {
    13     tree[p].l=l;
    14     tree[p].r=r;
    15     if (l==r)
    16     {
    17         tree[p].sum=1;
    18         return ;
    19     }
    20     int tem=(l+r)/2;
    21     build(l,tem,p*2);
    22     build(tem+1,r,p*2+1);
    23     tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
    24 }
    25 int find(int l,int r,int p)
    26 {
    27     if (tree[p].l>=l&&tree[p].r<=r) return tree[p].sum;
    28     int tem=(tree[p].l+tree[p].r)/2;
    29     if (l>tem) return find(l,r,p*2+1);
    30     else if (r<=tem) return find(l,r,p*2);
    31     return find(l,tem,p*2)+find(tem+1,r,p*2+1);
    32 }
    33 void un(int x,int p)
    34 {
    35     if (tree[p].l==tree[p].r)
    36     {
    37         tree[p].sum=0;
    38         return ;
    39     }
    40     if (tree[p*2].r>=x) un(x,p*2);
    41     else un(x,p*2+1);
    42     tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
    43 }
    44 int main()
    45 {
    46     int t,n,A[50005],a[50005],v[50005];
    47     int i,j,b,c,l,r,s;
    48     scanf("%d",&t);
    49     while (t--)
    50     {
    51         scanf("%d",&n);
    52         memset(v,0,sizeof(v));
    53         for (i=1;i<=n;i++) scanf("%d",&A[i]);
    54         build(1,n,1);
    55         for (i=n;i>1;i--)
    56         {
    57             b=i-(A[i]-A[i-1]);
    58             l=b;
    59             r=n;
    60             while (l<=r)
    61             {
    62                 c=(l+r)/2;
    63                 s=find(1,c,1);
    64                 if (s==b&&!v[c]) break;
    65                 if (s<b) l=c+1;
    66                 else r=c-1;
    67             }
    68             a[i]=c;
    69             v[c]=1;
    70             un(c,1);
    71         }
    72         for (i=1;i<=n;i++)
    73         {
    74             if (!v[i])
    75             {
    76                 a[1]=i;
    77                 break;
    78             }
    79         }
    80         for (i=1;i<n;i++) printf("%d ",a[i]);
    81         printf("%d
    ",a[i]);
    82     }
    83 }

              

  • 相关阅读:
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十一)
    install ubuntu on Android mobile phone
    Mac OS, Mac OSX 与Darwin
    About darwin OS
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十)
    Linux下编译安装qemu和libvirt
    libvirt(virsh命令总结)
    深入浅出 kvm qemu libvirt
    自然语言交流系统 phxnet团队 创新实训 项目博客 (九)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (八)
  • 原文地址:https://www.cnblogs.com/pblr/p/5023380.html
Copyright © 2011-2022 走看看