Cod sursa(job #2875894)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 22 martie 2022 16:00:41
Problema Cifre Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <bits/stdc++.h>
 
#define MOD 1000000007
#define NMAX 10
using namespace std;
 
int a, b, k, c;
 

long long _pow(long long a, long long b){
  long long ans = 1;
  for (; b; b >>= 1){
    if (b % 2) ans = ans * a % MOD;
    a = a * a % MOD;
  }
  return ans;
}

long long P[NMAX + 5], inv[NMAX + 5];
void prec(int n = NMAX-1){
  P[0] = inv[0] = 1;
  for (int i=1;i<=n;i++){
    P[i] = P[i-1] * i % MOD;
  }
  inv[n] = _pow(P[n], MOD - 2LL);
  for (int i=n-1;i>=1;i--)
    inv[i] = inv[i+1] * (i+1) % MOD;
}

template<typename T = long long>
long long comb(long long n, long long m){
  if (P[1] == 0) prec(NMAX);
  return P[n] * inv[m] % MOD * inv[n-m] % MOD;
}

void add(long long &a, long long b){
  a += b;
  if (a >= MOD) a -= MOD;
  if (a < 0) a += MOD;
}


int get_count(int x){
  vector<int> cif;
  while (x != 0){
    cif.push_back(x % 10);
    x /= 10;
  }
  reverse(cif.begin(), cif.end());
  
  // 0 - egal
  // 1 - mai mic
  vector<int> dp[2];
  dp[0].resize(10);
  dp[1].resize(10);
  dp[0][0] = 1;
  int ok = (c==0);
  for (auto it : cif){
    vector<int> dp2[2];
    dp2[0].resize(10);
    dp2[1].resize(10);
    for (int i=ok;i<=9;i++) {
      int add = (i == c);
      for (int j=9;j>=0;j--){
        if (j - add < 0){
          continue;
        }
        if (i < it){
          dp2[1][j] += dp[1][j - add] + dp[0][j - add];
        } else if (i == it){
          dp2[0][j] += dp[0][j - add];
          dp2[1][j] += dp[1][j - add];
        } else {
          dp2[1][j] += dp[1][j - add];
        }
      }
    }
    ok = 0;
    dp[0] = dp2[0];
    dp[1] = dp2[1];
  }

  int ans = 0;
  for (int i=k;i<=9;i++){
    ans += dp[0][i] + dp[1][i];  
  }

  if (c == 0){
    for (int j=1;j<cif.size();j++){
      for(int i=k;i<j;i++){
        ans += comb(j-1, i) * _pow(9, j-i);
      }
    }
  }
  return ans;
}
 
int main(){
  freopen("cifre.in","r",stdin);
  freopen("cifre.out","w",stdout);
  cin >> a >> b >> c >> k;

  cout << fixed << setprecision(4) << (long double)(get_count(b) - get_count(a - 1)) / (b - a + 1) << '\n';
  return 0;
}