链接: 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.
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.
1≤T≤5,1≤N≤50000
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.
1≤T≤5,1≤N≤50000
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\n",a[i]); 82 } 83 }