#include <stdio.h>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
using namespace std;
typedef long long LL;
int licz(LL n) {
if (n < 10) {
return n;
}
LL x = 1;
while (n) {
x *= n % 10;
n /= 10;
}
return licz(x);
}
const int M = 21;
LL newt[M][M];
LL all(LL x) {
vector<int> cc(10);
while(x) {
cc[x % 10]++;
x /= 10;
}
int n = 0;
for (int i = 1; i <= 9; i++) n += cc[i];
LL ret = 1;
for (int i = 1; i < 9; i++) {
ret *= newt[n][cc[i]];
n -= cc[i];
}
return ret;
}
vector<LL> tt, ta;
vector<int> tl, tcx;
void go(LL x, LL il, int cx, LL n) {
if (x > n || !il) return;
int c = licz(il);
if (c) {
tt.push_back(x);
tl.push_back(c);
tcx.push_back(cx);
ta.push_back(all(x));
//ret[c] += ile(x);
}
if (x > n/10+1) return;
for (int i = (!x ? 1 : x % 10); i <= 9; i++)
go(x * 10 + i, il*i, cx+1, n);
}
vector<int> cn;
LL ile(LL x, LL u, int cx) {
if (cx < cn.size()) return u;
vector<int> cc(10);
while(x) {
cc[x % 10]++;
x /= 10;
}
LL ret = 0;
for (int i = cn.size()-1; i >= 0; i--) {
for (int e = 1; e < cn[i]; e++) if(cc[e]) {
ret += u / newt[cx][cc[e]] * newt[cx-1][cc[e]-1];
}
if (!cc[cn[i]]) return ret;
u = u / newt[cx][cc[cn[i]]] * newt[cx-1][cc[cn[i]]-1];
cc[cn[i]]--;
cx--;
}
return ret + 1;
}
int main() {
for (int n = 0; n < M; n++) {
newt[n][0] = 1;
for (int i = 1; i <= n; i++) {
newt[n][i] = newt[n-1][i-1] + newt[n-1][i];
}
}
go(0LL, 1LL, 0, 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL);
//printf("%d\n", (int)t.size());
int q;
scanf("%d", &q);
while(q--) {
LL n;
scanf("%lld" , &n);
LL nn = n;
cn.clear();
while(nn) {
cn.push_back(nn % 10);
nn /= 10;
}
vector<LL> c(10);
for (int i = 1; i < tt.size(); i++) if (tt[i] <= n) {
c[tl[i]] += ile(tt[i], ta[i], tcx[i]);
}
c[0] = n;
for (int i = 1; i <= 9; i++) c[0] -= c[i];
for (int i = 0; i < 9; i++) printf("%lld ", c[i]);
printf("%lld\n", c[9]);
}
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 | #include <stdio.h> #include <vector> #include <algorithm> #include <utility> #include <map> using namespace std; typedef long long LL; int licz(LL n) { if (n < 10) { return n; } LL x = 1; while (n) { x *= n % 10; n /= 10; } return licz(x); } const int M = 21; LL newt[M][M]; LL all(LL x) { vector<int> cc(10); while(x) { cc[x % 10]++; x /= 10; } int n = 0; for (int i = 1; i <= 9; i++) n += cc[i]; LL ret = 1; for (int i = 1; i < 9; i++) { ret *= newt[n][cc[i]]; n -= cc[i]; } return ret; } vector<LL> tt, ta; vector<int> tl, tcx; void go(LL x, LL il, int cx, LL n) { if (x > n || !il) return; int c = licz(il); if (c) { tt.push_back(x); tl.push_back(c); tcx.push_back(cx); ta.push_back(all(x)); //ret[c] += ile(x); } if (x > n/10+1) return; for (int i = (!x ? 1 : x % 10); i <= 9; i++) go(x * 10 + i, il*i, cx+1, n); } vector<int> cn; LL ile(LL x, LL u, int cx) { if (cx < cn.size()) return u; vector<int> cc(10); while(x) { cc[x % 10]++; x /= 10; } LL ret = 0; for (int i = cn.size()-1; i >= 0; i--) { for (int e = 1; e < cn[i]; e++) if(cc[e]) { ret += u / newt[cx][cc[e]] * newt[cx-1][cc[e]-1]; } if (!cc[cn[i]]) return ret; u = u / newt[cx][cc[cn[i]]] * newt[cx-1][cc[cn[i]]-1]; cc[cn[i]]--; cx--; } return ret + 1; } int main() { for (int n = 0; n < M; n++) { newt[n][0] = 1; for (int i = 1; i <= n; i++) { newt[n][i] = newt[n-1][i-1] + newt[n-1][i]; } } go(0LL, 1LL, 0, 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL); //printf("%d\n", (int)t.size()); int q; scanf("%d", &q); while(q--) { LL n; scanf("%lld" , &n); LL nn = n; cn.clear(); while(nn) { cn.push_back(nn % 10); nn /= 10; } vector<LL> c(10); for (int i = 1; i < tt.size(); i++) if (tt[i] <= n) { c[tl[i]] += ile(tt[i], ta[i], tcx[i]); } c[0] = n; for (int i = 1; i <= 9; i++) c[0] -= c[i]; for (int i = 0; i < 9; i++) printf("%lld ", c[i]); printf("%lld\n", c[9]); } return 0; } |
English