SPOJ - ORDERS--- Ordering the Soldiers--- Find the original array according to the reverse order

Topic link:

https://vjudge.net/problem/SPOJ-ORDERS

Topic meaning:

Find the original array according to the reverse order of each number

Problem solving ideas:

For example:
n = 5
a[ n ] = { 0, 1, 2, 0, 1 };
for the 5th soldier, s[ 5 ] = { 1, 2, 3, 4, 5 };
and with it Corresponding a[ 4 ] = 1, that is to say, among the soldiers on his left, there is one smaller than him, and he ranks fourth among the soldiers on his left, so the fourth smallest rank in s[5] is him , corresponding to 4.
For the 4th soldier, s[ 4 ] = { 1, 2, 3, 5 }; no 4 means that the fourth smallest rank has been occupied
a[ 3 ] = 0, that is, the soldier to his left are higher than him, his rank is the largest, so the biggest thing 5 in s[4] is his rank
. For the third soldier, s[ 3 ] = { 1, 2, 3 };
a[ 2 ] = 2, it means that the level of the two soldiers on the left of the third soldier is lower than him, so take the smallest in s[3]--1
For the second soldier, s[ 2 ] = { 2, 3 };
a[ 1 ] = 1, which means that the soldier on the left of the second soldier is of lower level than him, so take the smallest one in s[2]--2
For the first soldier, s[ 1 ] = { 3 };
obviously the first Soldiers are ranked 3 ,


so the steps to solve the problem are:


add 1, 2, 3,...,n to the set s and
process each soldier in reverse:
    1. Find the largest number k in the a[i]th of s, and assign the value Give r[i], the rank of i soldier
    2. Remove k from s

 1 #include<bits/stdc++.h>
 2 #define lowbit(i) (i & (-i))
 3 using namespace std;
 4 const int maxn = 1000005;
 5 int a[maxn];
 6 int tree[maxn], n;
 7 int ans[maxn];
 8 void add(int x, int d)
 9 {
10     while(x <= n)
11         tree[x] += d, x += lowbit(x);
12 }
13 int sum(int x)
14 {
15     int ans = 0;
16     while(x)
17         ans += tree[x], x -= lowbit(x);
18     return ans;
19 }
20 int Find(int x)
21 {
22     int l = 1, r = n;
23     while(l < r)
24     {
25         int mid = (l + r) / 2;
26         if(sum(mid) >= x)
27             r = mid;
28         else l = mid + 1;
29     }
30     return r;
31 }
32 int main()
33 {
34     int T;
35     scanf("%d", &T);
36     while(T--)
37     {
38         memset(tree, 0, sizeof(tree));
39         scanf("%d", &n);
40         for(int i = 1; i <= n; i++)add(i, 1), scanf("%d", &a[i]);
41         for(int i = n; i >= 1; i--)
42             ans[i] = Find(i - a[i]), add(ans[i], -1);
43         printf("%d", ans[1]);
44         for(int i = 2; i <= n; i++)
45             printf(" %d", ans[i]);
46         puts("");
47     }
48     return 0;
49 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325051543&siteId=291194637