A rhyme scheme is the pattern of rhymes at the end of each line of a poem or song. It is usually referred to by using letters to indicate which lines rhyme; lines designated with the same letter all rhyme with each other.
e.g., the following "poem'' of 44 lines has an associated rhyme scheme "ABBA''
1 —— 9999 bugs in the code A
2 —— Fix one line B
3 —— Should be fine B
4 —— 100100 bugs in the code A
This essentially means that line 11 and 44 rhyme together and line 22 and 33 rhyme together.
The number of different possible rhyme schemes for an nn-line poem is given by the Bell numbers. For example, B_3 = 5B3=5, it means there are five rhyme schemes for a three-line poem: AAA, AAB, ABA, ABB, and ABC.
The question is to output the kk-th rhyme scheme in alphabetical order for a poem of nn lines.For example: the first rhyme scheme of a three-line poem is "AAA'', the fourth rhyme scheme of a three-line poem is ABB''.
InputFile
The first line of the input gives the number of test cases, TT (1 \leq T \leq 100001≤T≤10000). TT test cases follow.
Each test case contains a line with two integers nn and kk.
1 \leq n \leq 26, 1 \leq k \leq B_n1≤n≤26,1≤k≤Bn (B_nBn is the nn-th of Bell numbers)
OutputFile
For each test case, output one line containing Case #x: y, where xx is the test case number (starting from 11) and yy is the rhyme scheme contains uppercase letters.
样例输入
7 1 1 2 1 3 1 3 2 3 3 3 4 3 5
样例输出
Case #1: A Case #2: AA Case #3: AAA Case #4: AAB Case #5: ABA Case #6: ABB Case #7: ABC
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1000000007; const int maxn = 305; int T, n; __int128 k; __int128 dp[36][36]; int res[maxn]; inline __int128 read() { __int128 x = 0, f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } inline __int128 dfs1(int id, int limit) { if (id == n + 1)return 1; if (~dp[id][limit]) return dp[id][limit]; __int128 tot = 0; for (register int i = 0; i <= limit; ++i) { tot += dfs1(id + 1, max(limit, i + 1)); } return dp[id][limit] = tot; } inline void solve(int id, int limit, __int128 leave) { if (id == n + 1) { for (register int i = 1; i <= n; ++i) { printf("%c", res[i] + 'A'); } printf("\n"); return; } for (register int i = 0; i <= limit; ++i) { __int128 cur = max(limit, i + 1); if (dp[id + 1][cur] >= leave) { res[id] = i; solve(id + 1, cur, leave); break; } else { leave -= dp[id + 1][cur]; } } } int Case; int main() { #ifndef ONLINE_JUDGE //freopen("1.txt", "r", stdin); #endif scanf("%d", &T); while (T--) { scanf("%d%lld", &n,&k); //k = read(); for (register int i = 0; i <= 30; ++i) { for (register int j = 0; j <= 30; ++j) { dp[i][j] = -1; } } for (register int i = 0; i <= 30; ++i)dp[n + 1][i] = 1; dfs1(1, 0); printf("Case #%d: ", ++Case); solve(1, 0, k); } return 0; }