Advertisement
volochai

H. Lucky numbers

Dec 23rd, 2022
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.82 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define ll long long
  4. #define all(x) (x).begin(), (x).end()
  5. #define rall(x) (x).rbegin(), (x).rend()
  6. #define boost ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
  7. #define watch(x) cout << (#x) << " : " << x << '\n'
  8.  
  9. using namespace std;
  10.  
  11. const int N = 111;
  12. const int DIG = 10;
  13. const int SUM = N * DIG;
  14.  
  15. const int MOD = 1e9 + 7;
  16.  
  17. ll cnt[N][SUM][DIG];
  18. ll ruk[N][SUM][DIG + 1];
  19.  
  20. ll binpow(ll a, ll n) {
  21.     ll res = 1ll;
  22.     while (n) {
  23.         if (n & 1)
  24.             res = (res * a) % MOD;
  25.         a = (a * a) % MOD;
  26.         n >>= 1;
  27.     }
  28.     return res;
  29. }
  30.  
  31. ll inverse_element(ll a) {
  32.     return binpow(a, MOD - 2);
  33. }
  34.  
  35. ll divide(ll a, ll b) {
  36.     return (a * inverse_element(b)) % MOD;
  37. }
  38.  
  39. ll fact[N];
  40.  
  41. ll C(ll k, ll n) {
  42.     return divide(fact[n], (fact[k] * fact[n - k]) % MOD);
  43. }
  44.  
  45. void solve() {
  46.     int n;
  47.     cin >> n;
  48.  
  49.     fact[0] = fact[1] = 1;
  50.     for (int i = 2; i < N; i++)
  51.         fact[i] = (fact[i - 1] * i) % MOD;
  52.  
  53.     for (int d = 0; d < DIG; d++)
  54.         ruk[0][0][d] = 1;
  55.  
  56.     for (int i = 1; i <= n; i++) {
  57.         for (int blocked = 0; blocked <= DIG; blocked++) {
  58.             for (int d = 0; d < DIG; d++) {
  59.                 if (d == blocked)
  60.                     continue;
  61.                 for (int target = 0; target < SUM; target++) {
  62.                     if (target + d >= SUM)
  63.                         break;
  64.                     ruk[i][target + d][blocked] += ruk[i - 1][target][blocked];
  65.                     if (ruk[i][target + d][blocked] >= MOD)
  66.                         ruk[i][target + d][blocked] -= MOD;
  67.                 }
  68.             }
  69.         }
  70.     }
  71.  
  72.     for (int d = 0; d < DIG; d++)
  73.         for (int use = 0; use <= n; use++) {
  74.             for (int sum = 0; sum < SUM; sum++) {
  75.                 if (sum + use * d >= SUM)
  76.                     break;
  77.                 int ost_nums = n - use;
  78.                 cnt[use][sum + use * d][d] += (ruk[ost_nums][sum][d] * C(use, n)) % MOD;
  79.                 cnt[use][sum + use * d][d] %= MOD;
  80.             }
  81.         }
  82.  
  83.     for (int d = 0; d < DIG; d++) {
  84.         ll ans = 0ll;
  85.         for (int sum = 0; sum < SUM; sum++) {
  86.             for (int use_left = 0; use_left <= n; use_left++) {
  87.                 for (int use_right = use_left; use_right <= n; use_right++) {
  88.                     if (!use_left && !use_right)
  89.                         continue;
  90.                     int tot = use_left + use_right;  
  91.  
  92.                     ll ways = (cnt[use_left][sum][d] * cnt[use_right][sum][d]) % MOD;
  93.                     if (use_left != use_right) ways = (ways * 2) % MOD;
  94.  
  95.                     ans += (ways * tot) % MOD;
  96.                     ans %= MOD;
  97.                 }
  98.             }
  99.         }
  100.         cout << ans << ' ';
  101.     }
  102. }
  103.  
  104. signed main() {
  105.     boost;
  106.     solve();
  107.     return 0;
  108. }
  109.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement