标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9660 | Accepted: 6219 |
Description
Input
Output
Sample Input
5 1 2 1 0
Sample Output
2 4 5 3 1
Source
题目大意:
就是说,让你求出一个1到n的排列,但是,一开始,这个排列只告诉了你从第二个数字开始的比这个数字小的数的个数。
解题思路:
刚开始想了好久,还是自己太弱,对于数学方面的问题还应该多做题,CQ省队爷告诉我,应该先由一般的规律推出来如果你要确定某个数字p,那么我们就要知道p的前面有多少个数字比它小,记为m,p的后面有多少个数字比他小,记为n,那么p的位置就该在这个数列中的第m+n+1处,我们就二分这个p,拿每次得到的mid来和m+n+1来比较大小,如果m+n+1>mid就说明mid取小了,这个时候,我们就把left = mid+1;如果m+n+1<mid,那就说明mid取大了,这个时候我们就要把mid = right.
关于一个数字后面比他小的数字的个数怎么求解的问题,其实可以用树状数组来搞定。
关于一个数字前面有多少个数字比他小的问题,我们再输入的过程中已经知道了。
代码:
1 # include<cstdio> 2 # include<iostream> 3 # include<fstream> 4 # include<algorithm> 5 # include<functional> 6 # include<cstring> 7 # include<string> 8 # include<cstdlib> 9 # include<iomanip> 10 # include<numeric> 11 # include<cctype> 12 # include<cmath> 13 # include<ctime> 14 # include<queue> 15 # include<stack> 16 # include<list> 17 # include<set> 18 # include<map> 19 20 using namespace std; 21 22 const double PI=4.0*atan(1.0); 23 24 typedef long long LL; 25 typedef unsigned long long ULL; 26 27 # define inf 999999999 28 # define MAX 8000+4 29 30 int a[MAX]; 31 int ans[MAX]; 32 int tree[MAX]; 33 34 int n; 35 36 int read ( int pos ) 37 { 38 int ans = 0; 39 while ( pos > 0 ) 40 { 41 ans+=tree[pos]; 42 pos-=pos&(-pos); 43 } 44 return ans; 45 } 46 47 void update ( int pos,int val ) 48 { 49 while ( pos <= n ) 50 { 51 tree[pos]+=val; 52 pos+=pos&(-pos); 53 } 54 } 55 56 int my_search ( int k ) 57 { 58 int left = 1, right = n; 59 while ( left < right ) 60 { 61 int mid = ( left+right )>>1; 62 int num = read (mid); 63 if ( mid - 1 < num+k ) 64 { 65 left = mid+1; 66 } 67 else 68 { 69 right = mid; 70 } 71 } 72 return left; 73 } 74 75 int main(void) 76 { 77 while ( scanf("%d",&n)!=EOF ) 78 { 79 memset(tree,0,sizeof(tree)); 80 memset(ans,0,sizeof(ans)); 81 a[1] = 0; 82 for ( int i = 2;i <= n;i++ ) 83 scanf("%d",&a[i]); 84 for ( int i = n;i >= 1;i-- ) 85 { 86 int k = my_search(a[i]); 87 update(k,1); 88 ans[i] = k; 89 } 90 91 for ( int i = 1;i <= n;i++ ) 92 printf("%d\n",ans[i]); 93 } 94 95 96 97 return 0; 98 }
标签:
原文地址:http://www.cnblogs.com/wikioibai/p/4397257.html