码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-12-06 20:49:57      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

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

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?\n: );
77     }
78     return 0;
79 }

 

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

标签:

原文地址:http://www.cnblogs.com/a1225234/p/5024340.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!