#include #include #include #include #include #include #include #include #include #include // #include "Src/Number/IntegerDivision.hpp" // #include "Src/Utility/BinarySearch.hpp" // #include "Src/Sequence/CompressedSequence.hpp" // #include "Src/Sequence/RunLengthEncoding.hpp" // #include "Src/Algebra/Group/AdditiveGroup.hpp" // #include "Src/DataStructure/FenwickTree/FenwickTree.hpp" // #include "Src/DataStructure/SegmentTree/SegmentTree.hpp" // #include "Src/DataStructure/DisjointSetUnion/DisjointSetUnion.hpp" // #include "Src/DataStructure/Heap/BinaryHeap.hpp" namespace zawa {} using namespace zawa; // #include "atcoder/modint" // using mint = atcoder::modint998244353; // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #pragma GCC target("avx2") // #pragma GCC optimize("O3") // #pragma GCC optimize("unroll-loops") using namespace std; template ostream& operator<<(ostream& os, const pair& p) { os << '(' << p.first << ',' << p.second << ')'; return os; } template ostream& operator<<(ostream& os, const vector& v) { for (int i = 0 ; i < ssize(v) ; i++) os << v[i] << (i + 1 == ssize(v) ? "" : " "); return os; } vector solve(long long N, long long K) { vector cnt(10); for (int i = 1 ; i < 10 ; i++) for (int j = 0 ; j < 10 ; j++) for (int k = 0 ; k < 10 ; k++) if (i != j and j != k and i != k) cnt[i] += N; int head = 1; while (cnt[head] < K) { K -= cnt[head]; head++; } assert(head < 10); int sec = 0; while (true) { if (head == sec) { sec++; continue; } if (8LL * N < K) { K -= 8 * N; sec++; } else break; } vector low, up; for (int i = 0 ; i < 10 ; i++) if (head != i and sec != i) (i < sec ? low : up).push_back(i); if (K <= N * ssize(low)) { assert(low.size()); long long len = (K + ssize(low) - 1) / ssize(low); assert(len >= 1); K -= (len - 1) * ssize(low); assert(K <= ssize(low)); return vector{len+2,head,sec,low[K - 1]}; } K -= N * ssize(low); assert(up.size()); long long len = N - (K - 1) / ssize(up); K -= (K - 1) / ssize(up) * ssize(up); assert(K <= ssize(up)); return vector{len+2,head,sec,up[K - 1]}; } vector naive(long long N, long long K) { vector cur; for (int head = 1 ; head < 10 ; head++) for (int mid = 0 ; mid < 10 ; mid++) for (int tail = 0 ; tail < 10 ; tail++) if (head != mid and mid != tail and tail != head) for (int len = 1 ; len <= N ; len++) cur.push_back(string(1,head+'0')+string(len,mid+'0')+string(1,tail+'0')); ranges::sort(cur); string ans = cur[K - 1]; // for (auto a : cur) // cout << a << endl; return vector{ssize(ans),ans[0]-'0',ans[1]-'0',ans.back()-'0'}; // return vector{ans[0]-'0',ans[1]-'0'}; } int main() { cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(20); #if !defined DEBUG int T; cin >> T; while (T--) { long long N, K; cin >> N >> K; cout << solve(N,K) << '\n'; // cout << naive(N,K) << endl; } #else mt19937_64 mt{random_device{}()}; for (int testcase = 0 ; ; ) { cerr << "----------" << ++testcase << "----------" << endl; int N = mt() % 50 + 1; int K = mt() % (648 * N) + 1; auto a = solve(N,K), b = naive(N,K); if (a != b) { // print testcase cout << 1 << endl; cout << N << ' ' << K << endl; cerr << "you: " << a << endl; cout << "correct: " << b << endl; exit(0); } } #endif }