康托展开模板

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <cmath>

using namespace std;
using ll = long long;

const int MAXN = 21;
ll fact[MAXN];
int n;
vector<int> bit;

void update(int i, int delta) {
    for (; i <= n; i += i & -i) {
        bit[i] += delta;
    }
}

int query(int i) {
    int sum = 0;
    for (; i > 0; i -= i & -i) {
        sum += bit[i];
    }
    return sum;
}

int find_kth(int k) {
    int pos = 0;
    int current_sum = 0;
    int log_n = 0;
    if (n > 0) log_n = floor(log2(n));

    for (int i = 1 << log_n; i > 0; i >>= 1) {
        if (pos + i <= n && current_sum + bit[pos + i] < k) {
            current_sum += bit[pos + i];
            pos += i;
        }
    }
    return pos + 1;
}

void precompute_factorials() {
    fact[0] = 1;
    for (int i = 1; i < MAXN; ++i) {
        fact[i] = fact[i - 1] * i;
    }
}

void solve() {
    int q;
    cin >> n >> q;
    precompute_factorials();

    while (q--) {
        char type;
        cin >> type;
        if (type == 'P') {
            ll k;
            cin >> k;
            k--; // 0-indexed rank

            bit.assign(n + 1, 0);
            for (int i = 1; i <= n; ++i) {
                update(i, 1);
            }

            vector<int> p(n);
            for (int i = 0; i < n; ++i) {
                ll divisor = fact[n - 1 - i];
                ll quotient = k / divisor;
                k %= divisor;
                
                int num = find_kth(quotient + 1);
                p[i] = num;
                update(num, -1);
            }

            for (int i = 0; i < n; ++i) {
                cout << p[i] << (i == n - 1 ? "" : " ");
            }
            cout << "\n";

        } else { // type == 'Q'
            vector<int> p(n);
            bit.assign(n + 1, 0);
            for (int i = 1; i <= n; ++i) {
                update(i, 1);
            }

            ll rank = 0;
            for (int i = 0; i < n; ++i) {
                cin >> p[i];
                rank += (ll)(query(p[i] - 1)) * fact[n - 1 - i];
                update(p[i], -1);
            }
            cout << rank + 1 << "\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    solve();
    return 0;
}

posted @ 2025-11-18 10:16  Marinaco  阅读(4)  评论(0)    收藏  举报
//雪花飘落效果