• BC 65 ZYB's Premutation (线段树+二分搜索)


    题目简述:有一个全排列,一直每个前缀区间的逆序对数,还原这个排列。

    fi记录逆序对数,pi记录该位置数值,则k=fi-f(i-1)表示前i-1个数比pi大的数的个数,那么只要在剩余元素求出按大小顺序第i-k个数字即可。

    线段树+二分搜索,线段树bit[i]记录i的在剩余元素的排名顺序。

     1 /*******************************
     2 
     3 Date    : 2015-12-06 19:49:59
     4 Author  : WQJ (1225234825@qq.com)
     5 Link    : http://www.cnblogs.com/a1225234/
     6 Name     : 
     7 
     8 ********************************/
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <algorithm>
    12 #include <cmath>
    13 #include <cstring>
    14 #include <string>
    15 #include <set>
    16 #include <vector>
    17 #include <queue>
    18 #include <stack>
    19 #define LL long long
    20 using namespace std;
    21 int a[5000+10];
    22 int bit[5000+10];
    23 int ans[5000+10];
    24 int n;
    25 int lowbit(int i)
    26 {
    27     return i&-i;
    28 }
    29 int sum(int i)
    30 {
    31     int s=0;
    32     while(i>0)
    33     {
    34         s+=bit[i];
    35         i-=lowbit(i);
    36     }
    37     return s;
    38 }
    39 void add(int i,int a)
    40 {
    41     while(i<=n)
    42     {
    43         bit[i]+=a;
    44         i+=lowbit(i);
    45     }
    46 }
    47 int main()
    48 {    
    49     freopen("in.txt","r",stdin);
    50     int i,j;
    51     int T;
    52     scanf("%d",&T);
    53     while(T--)
    54     {
    55         scanf("%d",&n);
    56         for(i=1;i<=n;i++)    scanf("%d",&a[i]);    
    57         a[0]=0;
    58         memset(bit,0,sizeof(bit));
    59         for(i=1;i<=n;i++)    add(i,1);    /*用树状数组记录i的大小排名*/
    60         for(i=n;i>=1;i--)
    61         {
    62             int temp=a[i]-a[i-1];
    63             temp=i-temp;        //排在第temp的数
    64             int l=1,r=n,mid;
    65             int k=r;
    66             while(r>=l)
    67             {
    68                 mid=(r+l)/2;
    69                 if(sum(mid)>=temp)    {k=mid;r=mid-1;}
    70                 else    l=mid+1;
    71             }
    72             ans[i]=k;
    73             add(ans[i],-1);
    74         }
    75         for(i=1;i<=n;i++)
    76             printf("%d%c",ans[i],i==n?'
    ':' ');
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    linux命令行打印图片
    linux 命令行打印二维码
    ReactNative DeviceEventEmitter
    python操作Excel的几种方式
    python 爬虫实例(二)
    各种软件安装的URL
    python 爬虫实例(一)
    eclipse的maven中需要把jar的包文件登入到自己的仓库里面的操作
    关于Maven项目build时出现No compiler is provided in this environment的处理
    eclipse和maven生成web项目的war包的操作方法
  • 原文地址:https://www.cnblogs.com/a1225234/p/5024340.html
Copyright © 2020-2023  润新知