11525 (tree array + binary)
Given k and n, You need to output the nth series in Lexicographic Order.
And the question to n is n = S1 (k-1 )! + S2. (K-2 )! +... + Sk-1 * 1! + Sk * 0! (0 =
We can know the number of si numbers that are smaller than a [I] After I. In this way, we first think of set, but set cannot be accessed in sequence, so we can use a tree array, set 1 at initial time, eliminate the post 0, and then calculate the position of si + 1 in binary mode.
The Code is as follows:
#include
#include
#include
#include
#include
#include #include
#include
#include
#include
#include
#include
#include
using namespace std; #define LL long long const int maxn = 50005;const int INF = 1000000000;//freopen("input.txt", "r", stdin);int c[2 * maxn], s[maxn], ans[maxn], k;int lowbit(int x) {return x&(-x);}int sum(int x) {int ret = 0;while(x > 0) {ret += c[x];x -= lowbit(x);}return ret;}void add(int x) {while(x <= k) {c[x] += 1; x += lowbit(x);}}void subtract(int x) {while(x <= k) {c[x] -= 1; x += lowbit(x);}}int main() {int t; scanf("%d", &t);while(t--) {memset(c, 0, sizeof(c));cin >> k;for(int i = 1; i <= k; i++) add(i);for(int i = 1; i <= k; i++) {int tmp; cin >> tmp;int le = 1, ri = k;while(le < ri) {int mi = (le + ri) >> 1;int tsum = sum(mi);if(sum(mi) >= tmp + 1) ri = mi;else le = mi + 1;}ans[i] = ri;subtract(ans[i]);}printf("%d", ans[1]);for(int i = 2; i <= k; i++) printf(" %d", ans[i]);printf("\n");}return 0;}