#pragma GCC optimize ("Ofast")
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define FOR(i, a, b) for (auto i=(a); i<(b); i++)
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()
#ifdef DEBUG
#include "debug.h"
#else
#define dbg(...) 0
#endif
const long long maxN = 1ll << 60, maxL = 18;
long long fact[maxL + 1];
std::unordered_map <long long, int> M;
std::unordered_set <long long> nonzeroProds = {
1, 3, 7, 9,
//2
2, 12, 21, 112, 126, 162, 216, 729, 972, 1134, 1728, 1792, 2187, 8748, 13122, 14336, 33614, 61236, 93312, 268912, 314928, 321489, 393216, 1229312, 1411788, 1741824, 3111696, 7112448, 9633792, 11239424, 116169984, 368947264, 1811939328,
//4
4, 14, 27, 72, 98, 189, 294, 1161216, 128421199872,
//5
5, 15, 35, 75, 135, 175, 315, 1575, 1715, 3375, 59535, 77175,
//6
6, 16, 28, 32, 48, 84, 128, 144, 147, 168, 224, 288, 378, 441, 448, 672, 686, 784, 882, 1344, 1764, 1944, 2646, 2744, 6174, 6272, 8192, 11664, 18144, 23328, 24192, 27216, 28672, 34992, 41472, 49392, 67228, 71442, 96768, 111132, 122472, 139968, 148176, 163296, 214326, 221184, 236196, 331776, 642978, 666792, 1382976, 1492992, 1778112, 1843968, 2117682, 2667168, 2939328, 3211264, 3687936, 9437184, 9483264, 13226976, 13716864, 19361664, 46294416, 69441624, 71663616, 133413966, 169869312, 184473632, 226492416, 914838624, 1162261467, 1792336896, 2113929216, 3281116734, 3699376128, 4444263936, 11329339392, 23612624896, 913217421312, 13884223438848, 1438916737499136, 3416267673274176,
//8
8, 18, 24, 36, 42, 49, 63, 64, 81, 192, 243, 324, 343, 432, 486, 648, 864, 896, 1176, 1323, 1372, 2268, 4116, 12348, 13824, 14112, 18432, 23814, 32928, 42336, 43218, 112896, 124416, 131712, 137781, 177147, 413343, 691488, 941192, 1166886, 1361367, 1417176, 3779136, 4148928, 33718272, 1194891264, 1783627776, 4182119424, 1121144263281, 112717121716224, 727326941773824
};
long long evalDigsProd(long long n)
{
long long prod = n > 0;
for (; n != 0; n /= 10)
prod *= n % 10;
return prod;
}
int compMrec(long long n)
{
if (not M.count(n))
M[n] = compMrec(evalDigsProd(n));
return M[n];
}
void compM()
{
FOR(i, 0, 10)
M[i] = i;
for (long long m2 = 1; m2 < maxN; m2 *= 2)
for (long long m3 = m2; m3 < maxN; m3 *= 3)
for (long long m5 = m3; m5 < maxN; m5 *= 5)
for (long long m7 = m5; m7 < maxN; m7 *= 7)
compMrec(m7);
}
struct Multiset
{
std::array <int, 10> cnt;
int sum = 0;
long long nom, den = 1;
Multiset(const std::array <int, 10>& in)
{
assert(in[0] == 0);
FOR(i, 0, 10)
{
sum += cnt[i] = in[i];
den *= fact[cnt[i]];
}
nom = fact[sum];
}
long long getCombs()
{
return nom / den;
}
void incr(int d)
{
nom = fact[++sum];
den *= ++cnt[d];
}
void decr(int d)
{
nom = fact[--sum];
den /= cnt[d]--;
}
long long getCombsWithoutEachBelow(int d)
{
int s = 0;
FOR(i, 1, d)
s += cnt[i];
return fact[sum-1] * s / den;
}
};
std::vector <std::array <int, 10> > multis[10];
void compMultis(int dig = 1, int prefCnt = 0, long long prefProd = 1ll)
{
static std::array <int, 10> digCnt {};
if (dig == 10)
{
if (nonzeroProds.contains(prefProd) and prefCnt != 0)
multis[M[prefProd]].push_back(digCnt);
return;
}
FOR(currCnt, 0, maxL-prefCnt+1)
{
digCnt[dig] = currCnt;
compMultis(dig+1, prefCnt + currCnt, prefProd);
prefProd *= dig;
}
}
long long countLower(const std::string& T, Multiset S)
{
if (S.sum > SZ(T))
return 0;
if (S.sum < SZ(T))
return S.getCombs();
long long ret = 0;
for (auto& c : T)
{
int dig = c - '0';
ret += S.getCombsWithoutEachBelow(dig);
if (S.cnt[dig] == 0)
break;
S.decr(dig);
}
if (S.sum == 0)
ret++;
return ret;
}
void solve()
{
char buff[42];
scanf ("%s", buff);
std::string n(buff);
long long res[10] = {};
res[0] = atoll(buff);
FOR(d, 1, 10)
{
for (const auto& multi : multis[d])
res[d] += countLower(n, Multiset(multi));
res[0] -= res[d];
}
FOR(d, 0, 10)
printf("%lld ", res[d]);
printf("\n");
}
int main()
{
fact[0] = 1;
FOR(i, 1, maxL+1)
fact[i] = fact[i-1] * i;
compM();
compMultis();
int tc = 1;
scanf ("%d", &tc);
FOR(cid, 1, tc+1)
solve();
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | #pragma GCC optimize ("Ofast") #define _USE_MATH_DEFINES #include <bits/stdc++.h> #define FOR(i, a, b) for (auto i=(a); i<(b); i++) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() #ifdef DEBUG #include "debug.h" #else #define dbg(...) 0 #endif const long long maxN = 1ll << 60, maxL = 18; long long fact[maxL + 1]; std::unordered_map <long long, int> M; std::unordered_set <long long> nonzeroProds = { 1, 3, 7, 9, //2 2, 12, 21, 112, 126, 162, 216, 729, 972, 1134, 1728, 1792, 2187, 8748, 13122, 14336, 33614, 61236, 93312, 268912, 314928, 321489, 393216, 1229312, 1411788, 1741824, 3111696, 7112448, 9633792, 11239424, 116169984, 368947264, 1811939328, //4 4, 14, 27, 72, 98, 189, 294, 1161216, 128421199872, //5 5, 15, 35, 75, 135, 175, 315, 1575, 1715, 3375, 59535, 77175, //6 6, 16, 28, 32, 48, 84, 128, 144, 147, 168, 224, 288, 378, 441, 448, 672, 686, 784, 882, 1344, 1764, 1944, 2646, 2744, 6174, 6272, 8192, 11664, 18144, 23328, 24192, 27216, 28672, 34992, 41472, 49392, 67228, 71442, 96768, 111132, 122472, 139968, 148176, 163296, 214326, 221184, 236196, 331776, 642978, 666792, 1382976, 1492992, 1778112, 1843968, 2117682, 2667168, 2939328, 3211264, 3687936, 9437184, 9483264, 13226976, 13716864, 19361664, 46294416, 69441624, 71663616, 133413966, 169869312, 184473632, 226492416, 914838624, 1162261467, 1792336896, 2113929216, 3281116734, 3699376128, 4444263936, 11329339392, 23612624896, 913217421312, 13884223438848, 1438916737499136, 3416267673274176, //8 8, 18, 24, 36, 42, 49, 63, 64, 81, 192, 243, 324, 343, 432, 486, 648, 864, 896, 1176, 1323, 1372, 2268, 4116, 12348, 13824, 14112, 18432, 23814, 32928, 42336, 43218, 112896, 124416, 131712, 137781, 177147, 413343, 691488, 941192, 1166886, 1361367, 1417176, 3779136, 4148928, 33718272, 1194891264, 1783627776, 4182119424, 1121144263281, 112717121716224, 727326941773824 }; long long evalDigsProd(long long n) { long long prod = n > 0; for (; n != 0; n /= 10) prod *= n % 10; return prod; } int compMrec(long long n) { if (not M.count(n)) M[n] = compMrec(evalDigsProd(n)); return M[n]; } void compM() { FOR(i, 0, 10) M[i] = i; for (long long m2 = 1; m2 < maxN; m2 *= 2) for (long long m3 = m2; m3 < maxN; m3 *= 3) for (long long m5 = m3; m5 < maxN; m5 *= 5) for (long long m7 = m5; m7 < maxN; m7 *= 7) compMrec(m7); } struct Multiset { std::array <int, 10> cnt; int sum = 0; long long nom, den = 1; Multiset(const std::array <int, 10>& in) { assert(in[0] == 0); FOR(i, 0, 10) { sum += cnt[i] = in[i]; den *= fact[cnt[i]]; } nom = fact[sum]; } long long getCombs() { return nom / den; } void incr(int d) { nom = fact[++sum]; den *= ++cnt[d]; } void decr(int d) { nom = fact[--sum]; den /= cnt[d]--; } long long getCombsWithoutEachBelow(int d) { int s = 0; FOR(i, 1, d) s += cnt[i]; return fact[sum-1] * s / den; } }; std::vector <std::array <int, 10> > multis[10]; void compMultis(int dig = 1, int prefCnt = 0, long long prefProd = 1ll) { static std::array <int, 10> digCnt {}; if (dig == 10) { if (nonzeroProds.contains(prefProd) and prefCnt != 0) multis[M[prefProd]].push_back(digCnt); return; } FOR(currCnt, 0, maxL-prefCnt+1) { digCnt[dig] = currCnt; compMultis(dig+1, prefCnt + currCnt, prefProd); prefProd *= dig; } } long long countLower(const std::string& T, Multiset S) { if (S.sum > SZ(T)) return 0; if (S.sum < SZ(T)) return S.getCombs(); long long ret = 0; for (auto& c : T) { int dig = c - '0'; ret += S.getCombsWithoutEachBelow(dig); if (S.cnt[dig] == 0) break; S.decr(dig); } if (S.sum == 0) ret++; return ret; } void solve() { char buff[42]; scanf ("%s", buff); std::string n(buff); long long res[10] = {}; res[0] = atoll(buff); FOR(d, 1, 10) { for (const auto& multi : multis[d]) res[d] += countLower(n, Multiset(multi)); res[0] -= res[d]; } FOR(d, 0, 10) printf("%lld ", res[d]); printf("\n"); } int main() { fact[0] = 1; FOR(i, 1, maxL+1) fact[i] = fact[i-1] * i; compM(); compMultis(); int tc = 1; scanf ("%d", &tc); FOR(cid, 1, tc+1) solve(); return 0; } |
English