Submission

Status:

PPPPPPPPPPPPPPPPPPPP

Subtask/Task Score:

100/100

Score: 100

User: porpeang

Problemset: สุ่มสลับ

Language: cpp

Time: 0.002 second

Submitted On: 2026-10-05 22:14:25

#include <iostream>
#include <string>

using namespace std;

// ตารางเก็บค่า Factorial ล่วงหน้า (O(1) Lookup)
const long long FACT[] = {
    1,          // 0!
    1,          // 1!
    2,          // 2!
    6,          // 3!
    24,         // 4!
    120,        // 5!
    720,        // 6!
    5040,       // 7!
    40320,      // 8!
    362880,     // 9!
    3628800,    // 10!
    39916800,   // 11!
    479001600   // 12!
};

int main() {
    // เร่งการทำงานของ I/O
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N;
    if (!(cin >> N)) return 0;

    string s;
    cin >> s;

    // Bitmask เก็บตัวอักษรที่ยังไม่ได้ใช้ (เปิดบิตเป็น 1 ทั้งหมด N บิต)
    int mask = (1 << N) - 1;
    long long rank = 1;

    for (int i = 0; i < N; i++) {
        int char_idx = s[i] - 'A';

        // นับจำนวนตัวอักษรที่น้อยกว่า s[i] และยังไม่ถูกใช้ใน O(1)
        int smaller_unused_mask = mask & ((1 << char_idx) - 1);
        int count_smaller = __builtin_popcount(smaller_unused_mask);

        // คำนวณลำดับเพิ่ม
        rank += count_smaller * FACT[N - 1 - i];

        // ปิดบิตตัวอักษรที่ถูกใช้ไปแล้ว
        mask &= ~(1 << char_idx);
    }

    cout << rank << "\n";

    return 0;
}