Problem:
F: ごちうさ数
問題
ごちうさが大好きなAORイカちゃんは「ごちうさ数」を定義した。
ごちうさ数とは、 $10$ 進表記において「 $51?3$ 」を含む自然数のことである。
$?$ は $0$ 〜 $9$ のどの数字であってもよい。
$N$ 以下の自然数のうち、ごちうさ数の個数を求めよ。
制約
$1 \le N < 10^{18}$
入力
$N$
出力
ごちうさ数の個数を一行で出力せよ。また末尾に改行を出力せよ。
サンプル
サンプル入力 1
5124
サンプル出力 1
3
$5124$ 以下のごちうさ数は、$5103$ , $5113$ , $5123$ の 三つである。
サンプル入力 2
60000
サンプル出力 2
160
サンプル入力 3
100000
サンプル出力 3
200

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>

using namespace std;


int main() {
    string S; cin >> S;
    int N = S.size();

    // DP[i桁][下4桁][is_clear][is_less] := ごちうさ数の数
    // is_less -> 入力Sよりちいさいかどうか
    auto ok = [&](int n) {
        if (10000<=n)
            cerr << "だめ〜〜〜" << n << endl;

        int x1 = n / 1000;
        int x2 = (n%1000) / 100;
        int x4 = n%10;
        return x1 == 5 && x2 == 1 && x4 == 3;
    };
    vector DP(N+1, vector(10000, vector(2, vector<long long>(2))));
    DP[0][0][0][0] = 1;
    for (int i=0;i<N;i++) {
        int D = S[i] - '0';

        for (int j=0;j<10000;j++) {
            int nx_d3 = (j % 1000) * 10;
            
            // 0 -> 0
            DP[i+1][j][1][0] += DP[i][j][1][0];        
            if (ok(nx_d3+D))
                DP[i+1][nx_d3+D][1][0] += DP[i][j][0][0];        
            else
                DP[i+1][nx_d3+D][0][0] += DP[i][j][0][0];        

            // 0 -> 1
            for (int d=0;d<D;d++) {
                DP[i+1][j][1][1] += DP[i][j][1][0];        
                if (ok(nx_d3+d))
                    DP[i+1][nx_d3+d][1][1] += DP[i][j][0][0];        
                else
                    DP[i+1][nx_d3+d][0][1] += DP[i][j][0][0];        
            }

            // 1 -> 1
            for (int d=0;d<10;d++) {
                DP[i+1][j][1][1] += DP[i][j][1][1];        
                if (ok(nx_d3+d))
                    DP[i+1][nx_d3+d][1][1] += DP[i][j][0][1];        
                else
                    DP[i+1][nx_d3+d][0][1] += DP[i][j][0][1];        
            }
        }
    }
    long long res = 0;
    for (int i=0;i<10000;i++) {
        res += DP[N][i][1][0];
        res += DP[N][i][1][1];
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 33024
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
constexpr int MOD=998244353;

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  string S;
  cin>>S;
  for(auto &i:S)i-='0';
  int N=S.size();
  const int X=10000;
  set<int>ok;
  for(int i=0;i<10;i++){
    ok.insert(5100+i*10+3);
  }
  vector dp0(N,vector(X,0ll)),dp1=dp0,dp3=dp0,dp4=dp0;
  for(int i=0;i<S[0];i++){
    dp0[0][i]+=1;
  }
  dp1[0][S[0]]=1;
  for(int i=1;i<N;i++){
    for(int j=0;j<X;j++){
      for(int k=0;k<10;k++){
        if(ok.find((j*10+k)%X)!=ok.end()){
          dp3[i][(j*10+k)%X]+=dp0[i-1][j];
        }else{
          dp0[i][(j*10+k)%X]+=dp0[i-1][j];
        }
        dp3[i][(j*10+k)%X]+=dp3[i-1][j];
      }
      for(int k=0;k<S[i];k++){
        if(ok.find((j*10+k)%X)!=ok.end()){
          dp3[i][(j*10+k)%X]+=dp1[i-1][j];
        }else{
          dp0[i][(j*10+k)%X]+=dp1[i-1][j];
        }
        dp3[i][(j*10+k)%X]+=dp4[i-1][j];
      }
      if(ok.find((j*10+S[i])%X)!=ok.end()){
        dp4[i][(j*10+S[i])%X]+=dp1[i-1][j];
      }else{
        dp1[i][(j*10+S[i])%X]+=dp1[i-1][j];
      }
      dp4[i][(j*10+S[i])%X]+=dp4[i-1][j];
    }
  }
  ll ans=0;
  ans+=accumulate(dp3[N-1].begin(),dp3[N-1].end(),0ll);
  ans+=accumulate(dp4[N-1].begin(),dp4[N-1].end(),0ll);
  cout<<ans<<'\n';
}
accuracy: 1
time_ms: 10
memory_kb: 8852
final_rank: 2

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>

template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }

using lint = long long;
constexpr int D = 10000;

bool judge(int d) {
    d -= 3015;
    return d % 100 == 0 && 0 <= d && d <= 900;
}

void solve() {
    std::string s;
    std::cin >> s;
    std::reverse(s.begin(), s.end());

    auto dp = vec(2, vec(2, vec(D, 0LL)));
    dp[0][0][0] = dp[1][0][0] = 1;

    for (char c : s) {
        int d = c - '0';

        auto ndp = vec(2, vec(2, vec(D, 0LL)));

        for (int i = 0; i < 2; ++i) {
            for (int pd = 0; pd < D; ++pd) {
                for (int p = 0; p <= 9; ++p) {
                    int nd = (pd * 10 + p) % D;
                    int ni = (i || judge(nd));
                    ndp[0][ni][nd] += dp[0][i][pd];
                }

                for (int p = 0; p < d; ++p) {
                    int nd = (pd * 10 + p) % D;
                    int ni = (i || judge(nd));
                    ndp[1][ni][nd] += dp[0][i][pd];
                }

                {
                    int p = d;
                    int nd = (pd * 10 + p) % D;
                    int ni = (i || judge(nd));
                    ndp[1][ni][nd] += dp[1][i][pd];
                }
            }
        }

        std::swap(dp, ndp);
    }

    lint ans = 0;
    for (int pd = 0; pd < D; ++pd) ans += dp[1][1][pd];
    std::cout << ans << "\n";
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4084
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
#ifdef DEBUG_ 
#include "../program_contest_library/memo/dump.hpp"
#else
#define dump(...)
#endif
const ll INF = 1LL<<60;

ll dp[20][10010][2][2];
int main(void) {
    string s;
    cin >> s;
    const ll n = s.size();

    dp[0][0][0][0] = 1;
    REP(i, n) REP(j, 10000) REP(k, 2) REP(l, 2) {
        ll lim = k==0 ? s[i]-'0' : 9;
        REP(d, lim+1) {
            ll nj = (j*10 + d) % 10000, nk = k || d<lim, nl = l;
            if(nj/100 == 51 && nj%10 == 3) nl |= 1;
            dp[i+1][nj][nk][nl] += dp[i][j][k][l];
        }
    }

    ll ret = 0;
    REP(i, 10000) REP(j, 2) ret += dp[n][i][j][1];
    cout << ret << endl;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 8856
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define inf INT_MAX
#define INF LLONG_MAX
#define ll long long
#define ull unsigned long long
#define M (int)(1e9+7)
#define P pair<int,int>
#define PLL pair<ll,ll>
#define FOR(i,m,n) for(int i=(int)m;i<(int)n;i++)
#define RFOR(i,m,n) for(int i=(int)m;i>=(int)n;i--)
#define rep(i,n) FOR(i,0,n)
#define rrep(i,n) RFOR(i,n,0)
#define all(a) a.begin(),a.end()
#define IN(a,n) rep(i,n){ cin>>a[i]; }
const int vx[4] = {0,1,0,-1};
const int vy[4] = {1,0,-1,0};
#define PI 3.14159265
#define F first
#define S second
#define PB push_back
#define EB emplace_back
#define int ll
#define vi vector<int>
#define IP pair<int,P>
#define PP pair<P,P>
#define Yes(f){cout<<(f?"Yes":"No")<<endl;}
#define YES(f){cout<<(f?"YES":"NO")<<endl;}


string n;
int dp[21][10010][3][3];

bool judge(int n){
  if((n/100)!=51) return false;
  if(n%10!=3) return false;
  return true;
}


signed main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout<<fixed<<setprecision(20);
  cin>>n;

  dp[0][0][0][0]=1;
  rep(i,n.size()+1){
    rep(j,10000){
      rep(k,10){
        int nj=(j%1000*10+k);

        dp[i+1][nj][1][1]+=dp[i][j][1][1];

        if(judge(nj)) dp[i+1][nj][1][1]+=dp[i][j][0][1];
        else dp[i+1][nj][0][1]+=dp[i][j][0][1];

        if(k<n[i]-'0'){
          dp[i+1][nj][1][1]+=dp[i][j][1][0];

          if(judge(nj)) dp[i+1][nj][1][1]+=dp[i][j][0][0];
          else dp[i+1][nj][0][1]+=dp[i][j][0][0];
        }

        if(k==n[i]-'0'){
          dp[i+1][nj][1][0]+=dp[i][j][1][0];

          if(judge(nj)) dp[i+1][nj][1][0]+=dp[i][j][0][0];
          else dp[i+1][nj][0][0]+=dp[i][j][0][0];
        }
      }
    }
  }

  int ans=0;
  rep(j,10000){
    rep(s,2){
      ans+=dp[n.size()][j][1][s];
    }
  }

  cout<<ans<<endl;


}
accuracy: 1
time_ms: 10
memory_kb: 16604
final_rank: 8

code_snippet: #include <iostream>
#include <cstring>
using namespace std;

int len[5] = {5, 7, 5, 7, 7};
string N;
long long dp[21][10010][3][3]; // digit, last4, clear, smaller

bool judge(int n) {
  if ( (n/100) != 51) return false;
  if (n % 10 != 3) return false;
  return true;
}

int main() {
  while (cin >> N) {
    memset(dp, 0, sizeof(dp));
    dp[0][0][0][0] = 1;
    for (int i = 0; i <= N.size(); ++i) {
      for (int j = 0; j <= 9999; ++j) {
        for (int k = 0; k < 10; ++k) {
          int nj = (j % 1000) * 10 + k;

          // smaller -> smaller
          {
            // clear -> clear
            dp[i+1][nj][1][1] += dp[i][j][1][1];

            // nonclear -> 
            if (judge(nj)) dp[i+1][nj][1][1] += dp[i][j][0][1];
            else dp[i+1][nj][0][1] += dp[i][j][0][1];
          }

          // same -> smaller
          if (k < (int)(N[i] - '0')) {
            // clear -> clear
            dp[i+1][nj][1][1] += dp[i][j][1][0];

            // nonclear ->
            if (judge(nj)) dp[i+1][nj][1][1] += dp[i][j][0][0];
            else dp[i+1][nj][0][1] += dp[i][j][0][0];
          }

          // same -> same
          if (k == (int)(N[i] - '0')) {
            // clear -> clear
            dp[i+1][nj][1][0] += dp[i][j][1][0];

            // nonclear ->
            if (judge(nj)) dp[i+1][nj][1][0] += dp[i][j][0][0];
            else dp[i+1][nj][0][0] += dp[i][j][0][0];
          }
          
        }
      }
    }

    long long res = 0;
    for (int j = 0; j <= 9999; ++j) {
      for (int smaller = 0; smaller < 2; ++smaller) {
        res += dp[N.size()][j][1][smaller];
      }
    }

    cout << res << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 17996
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define int long long
using namespace std;

int dp[20][5][2][2];
string s,t="51?3@";

int dfs(int idx,int mat,bool tight=true,bool ok=false){
    if(idx==s.size())return ok;
    int res=dp[idx][mat][tight][ok];
    if(~res)return res;
    res=0;
    int x=s[idx]-'0';
    int r=(tight?x:9);
    for(int i=0;i<=r;i++){
        int nxt=(i+'0'==t[mat])||(t[mat]=='?');
        if(nxt&&(!ok))res+=dfs(idx+1,mat+nxt,tight&&i==r,nxt+mat==4 );
        else if(ok)res+=dfs(idx+1,4,tight&&i==r,ok);
        else{
            if(i==5)res+=dfs(idx+1,1,tight&&i==r,ok);
            else res+=dfs(idx+1,0,tight&&i==r,ok);
        }
    }
    return res;
}

signed main(){
    memset(dp,-1,sizeof(dp));
    cin>>s;
    cout<<dfs(0,0)<<endl;
}
accuracy: 0.036036036036036036
time_ms: 210
memory_kb: 3148
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define int long long
using namespace std;

int dp[20][5][2][2];
string s,t="51?3";

int dfs(int idx,int mat,bool tight=true,bool ok=false){
    if(idx==s.size())return ok;
    int res=dp[idx][mat][tight][ok];
    if(~res)return res;
    res=0;
    int x=s[idx]-'0';
    int r=(tight?x:9);
    for(int i=0;i<=r;i++){
        int nxt=(i+'0'==t[mat])||(t[mat]=='?');
        if(nxt&&!ok)res+=dfs(idx+1,mat+nxt,tight&&i==r,nxt+mat==4);
        if(ok)res+=dfs(idx+1,4,tight&&i==r,ok);
        else res+=dfs(idx+1,0,tight&&i==r,ok);
    }
    return res;
}

signed main(){
    memset(dp,-1,sizeof(dp));
    cin>>s;
    cout<<dfs(0,0)<<endl;
}
accuracy: 0.036036036036036036
time_ms: 490
memory_kb: 3188
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)   FOR(i,0,n)
#define pb emplace_back
typedef long long ll;
typedef pair<int,int> pint;

ll dp[19][10000][2][2];
bool ck(int c){
    if(c/1000==5&&c/100%10==1&&c%10==3) return true;
    return false;
}
int main(){
    string s;
    cin>>s;
    int n=s.size();
    dp[0][0][0][0]=1;
    rep(i,n)rep(j,10000)rep(k,2)rep(l,2){
        int ulim=l?9:s[i]-'0';
        rep(p,ulim+1){
            dp[i+1][(j*10+p)%10000][k||ck((j*10+p)%10000)][l||p<ulim]+=dp[i][j][k][l];
        }
    }
    ll ans=0;
    rep(i,10000)rep(k,2) ans+=dp[n][i][1][k];
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 8840
final_rank: 7

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	FULL_MATCH,
	ELSE,
};

ll SHISHIMARU;
ll length,POW[16];
ll num_array[20];
ll dp[20][10000][2][2];

ll getNUM(ll pre_num,ll next){
	return (10*pre_num+next)%10000;
}

bool is_OK(ll number){
	if((number/1000)%10 != 5)return false;
	if(number-5000 <= 99 || number-5000 >= 200)return false;
	if(number%10 != 3)return false;
	return true;
}

ll recursive(ll pre_num,ll digit,Type type,bool is_completed){

	if(digit == length){
		if(is_completed)return 1;
		else{
			return 0; //G数が成立しないならreturn 0;
		}
	}

	if(dp[digit][pre_num][type][is_completed] != -1){
		return dp[digit][pre_num][type][is_completed]; //計算済ならreturn
	}

	if(is_completed == true && type == ELSE){
		return dp[digit][pre_num][type][is_completed] = POW[length-digit];
	}else if(is_completed == true && type == FULL_MATCH){
		return dp[digit][pre_num][type][is_completed] = (SHISHIMARU%POW[length-digit])+1;
	}

	ll ret = 0;
	ll limit;
	if(type == FULL_MATCH){
		limit = num_array[digit]-1;
	}else{
		limit = 9;
	}

	ll tmp;

	for(int next = 0; next <= limit; next++){
		tmp =  getNUM(pre_num,next);
		ret += recursive(tmp,digit+1,ELSE,is_completed||is_OK(tmp));
	}

	if(type == FULL_MATCH){
		tmp = getNUM(pre_num,num_array[digit]);
		ret += recursive(tmp,digit+1,FULL_MATCH,is_completed||is_OK(tmp));
	}

	return dp[digit][pre_num][type][is_completed] = ret;
}


int main(){

	for(int i = 0; i < 16; i++){
		POW[i] = pow(10,i);
	}

	ll N;
	scanf("%lld",&N);

	if(N <= 5102){
		printf("0\n");
		return 0;
	}

	SHISHIMARU = N;

	stack<ll> S;

	//Nを桁別に分解する
	while(N > 0){
		S.push(N%10);
		N /= 10;
	}

	ll index = 0;

	while(!S.empty()){
		num_array[index++] = S.top();
		S.pop();
	}

	length = index;

	for(int digit = 0; digit <= length-1; digit++){
		for(int pre_num = 0; pre_num <= 9999; pre_num++){
			for(int p = 0; p <= 1; p++){
				for(int k = 0; k <= 1; k++){
					dp[digit][pre_num][p][k] = -1;
				}
			}
		}
	}

	printf("%lld\n",recursive(0,0,FULL_MATCH,false));

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 9008
final_rank: 4

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	FULL_MATCH,
	ELSE,
};

ll length,POW[16];
ll num_array[20];
ll dp[20][10000][2][2];

ll getNUM(ll pre_num,ll next){
	return (10*pre_num+next)%10000;
}

bool is_OK(ll number){
	if((number/1000)%10 != 5)return false;
	if(number-5000 <= 99 || number-5000 >= 200)return false;
	if(number%10 != 3)return false;
	return true;
}

ll recursive(ll pre_num,ll digit,Type type,bool is_completed){

	if(digit == length){
		if(is_completed)return 1;
		else{
			return 0; //G数が成立しないならreturn 0;
		}
	}

	if(dp[digit][pre_num][type][is_completed] != -1){
		return dp[digit][pre_num][type][is_completed]; //計算済ならreturn
	}

	if(is_completed == true && type == ELSE){
		return dp[digit][pre_num][type][is_completed] = POW[length-digit];
	}

	ll ret = 0;
	ll limit;
	if(type == FULL_MATCH){
		limit = num_array[digit]-1;
	}else{
		limit = 9;
	}

	ll tmp;

	for(int next = 0; next <= limit; next++){
		tmp =  getNUM(pre_num,next);
		ret += recursive(tmp,digit+1,ELSE,is_completed||is_OK(tmp));
	}

	if(type == FULL_MATCH){
		tmp = getNUM(pre_num,num_array[digit]);
		ret += recursive(tmp,digit+1,FULL_MATCH,is_completed||is_OK(tmp));
	}

	return dp[digit][pre_num][type][is_completed] = ret;
}


int main(){

	for(int i = 0; i < 16; i++){
		POW[i] = pow(10,i);
	}

	ll N;
	scanf("%lld",&N);

	if(N <= 5102){
		printf("0\n");
		return 0;
	}

	stack<ll> S;

	//Nを桁別に分解する
	while(N > 0){
		S.push(N%10);
		N /= 10;
	}

	ll index = 0;

	while(!S.empty()){
		num_array[index++] = S.top();
		S.pop();
	}

	length = index;

	for(int digit = 0; digit <= length-1; digit++){
		for(int pre_num = 0; pre_num <= 9999; pre_num++){
			for(int p = 0; p <= 1; p++){
				for(int k = 0; k <= 1; k++){
					dp[digit][pre_num][p][k] = -1;
				}
			}
		}
	}

	printf("%lld\n",recursive(0,0,FULL_MATCH,false));

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 9008
final_rank: 4

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	FULL_MATCH,
	ELSE,
};

ll length;
ll num_array[20];
ll dp[20][10000][2][2];

ll getNUM(ll pre_num,ll next){
	return (10*pre_num+next)%10000;
}

bool is_OK(ll number){
	stack<ll> S;
	while(number > 0){
		S.push(number%10);
		number /= 10;
	}
	int index = 0;
	ll work[4];

	while(!S.empty()){
		work[index++] = S.top();
		S.pop();
	}

	return (work[0] == 5 && work[1] == 1 && work[3] == 3);
}

ll recursive(ll pre_num,ll digit,Type type,bool is_completed){

	if(digit == length){
		if(is_completed)return 1;
		else{
			return 0; //G数が成立しないならreturn 0;
		}
	}

	if(dp[digit][pre_num][type][is_completed] != -1){
		return dp[digit][pre_num][type][is_completed]; //計算済ならreturn
	}

	if(is_completed == true && type == ELSE){
		return dp[digit][pre_num][type][is_completed] = pow(10,length-digit);
	}

	ll ret = 0;
	ll limit;
	if(type == FULL_MATCH){
		limit = num_array[digit]-1;
	}else{
		limit = 9;
	}

	ll tmp;

	for(int next = 0; next <= limit; next++){
		tmp =  getNUM(pre_num,next);
		ret += recursive(tmp,digit+1,ELSE,is_completed||is_OK(tmp));
	}

	if(type == FULL_MATCH){
		tmp = getNUM(pre_num,num_array[digit]);
		ret += recursive(tmp,digit+1,FULL_MATCH,is_completed||is_OK(tmp));
	}

	return dp[digit][pre_num][type][is_completed] = ret;
}


int main(){

	ll N;
	scanf("%lld",&N);

	if(N <= 5102){
		printf("0\n");
		return 0;
	}

	stack<ll> S;

	//Nを桁別に分解する
	while(N > 0){
		S.push(N%10);
		N /= 10;
	}

	ll index = 0;

	while(!S.empty()){
		num_array[index++] = S.top();
		S.pop();
	}

	length = index;

	for(int digit = 0; digit <= length-1; digit++){
		for(int pre_num = 0; pre_num <= 9999; pre_num++){
			for(int p = 0; p <= 1; p++){
				for(int k = 0; k <= 1; k++){
					dp[digit][pre_num][p][k] = -1;
				}
			}
		}
	}

	printf("%lld\n",recursive(0,0,FULL_MATCH,false));

	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 8980
final_rank: 12

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	FULL_MATCH,
	ELSE,
};

ll length,POW[16];;
ll memo[18][2]; //memo[初めてG数が成立した桁数][先頭桁から、Nと数が一致し続けているか] = 残りの桁を埋める場合の数
ll num_array[20];
ll dp[20][10000][2][2];

ll getNUM(ll pre_num,ll next){
	return (10*pre_num+next)%10000;
}

bool is_OK(ll number){
	stack<ll> S;
	while(number > 0){
		S.push(number%10);
		number /= 10;
	}
	int index = 0;
	ll work[4];

	while(!S.empty()){
		work[index++] = S.top();
		S.pop();
	}

	return (work[0] == 5 && work[1] == 1 && work[3] == 3);
}

ll recursive(ll pre_num,ll digit,Type type,bool is_completed){

	if(is_completed){
		return memo[digit-1][type]; //残りの桁を埋める場合の数をreturn
	}

	if(digit == length)return 0;

	if(dp[digit][pre_num][type][is_completed] != -1){
		return dp[digit][pre_num][type][is_completed]; //計算済ならreturn
	}

	ll ret = 0;
	ll limit;
	if(type == FULL_MATCH){
		limit = num_array[digit]-1;
	}else{
		limit = 9;
	}

	ll tmp;

	for(int next = 0; next <= limit; next++){
		tmp =  getNUM(pre_num,next);
		ret += recursive(tmp,digit+1,ELSE,is_completed||is_OK(tmp));
	}

	if(type == FULL_MATCH){
		tmp = getNUM(pre_num,num_array[digit]);
		ret += recursive(tmp,digit+1,FULL_MATCH,is_completed||is_OK(tmp));
	}

	return dp[digit][pre_num][type][is_completed] = ret;
}


int main(){

	for(int i = 0; i < 16; i++){ //最速の成立は3桁目(0オリジン) よって、最大残桁は14
		POW[i] = pow(10,i);
	}

	ll N;
	scanf("%lld",&N);

	if(N <= 5102){
		printf("0\n");
		return 0;
	}

	stack<ll> S;

	//Nを桁別に分解する
	while(N > 0){
		S.push(N%10);
		N /= 10;
	}

	ll index = 0;

	while(!S.empty()){
		num_array[index++] = S.top();
		S.pop();
	}

	length = index;

	int rest_digit;

	//先頭からの一致がfalseの場合のmemoを埋める
	for(int digit = 3; digit <= length-1; digit++){
		rest_digit = length-(digit+1);
		memo[digit][ELSE] = POW[rest_digit];
	}

	//先頭からの一致がtrueの場合のメモを埋める
	for(int digit = 3; digit <= length-1; digit++){
		rest_digit = length-(digit+1);
		memo[digit][FULL_MATCH] = (N%POW[rest_digit])+1; //+1は末尾0の分
	}

	for(int digit = 0; digit <= length-1; digit++){
		for(int pre_num = 0; pre_num <= 9999; pre_num++){
			for(int p = 0; p <= 1; p++){
				for(int k = 0; k <= 1; k++){
					dp[digit][pre_num][p][k] = -1;
				}
			}
		}
	}

	printf("%lld\n",recursive(0,0,FULL_MATCH,false));

	return 0;
}
accuracy: 0.5315315315315315
time_ms: 240
memory_kb: 8904
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	FULL_MATCH,
	ELSE,
};

ll length;
ll num_array[20];
ll dp[20][10000][2][2];

ll getNUM(ll pre_num,ll next){
	return (10*pre_num+next)%10000;
}

bool is_OK(ll number){
	stack<ll> S;
	while(number > 0){
		S.push(number%10);
		number /= 10;
	}
	int index = 0;
	ll work[4];

	while(!S.empty()){
		work[index++] = S.top();
		S.pop();
	}

	return (work[0] == 5 && work[1] == 1 && work[3] == 3);
}

ll recursive(ll pre_num,ll digit,Type type,bool is_completed){

	if(digit == length){
		if(is_completed)return 1;
		else{
			return 0; //G数が成立しないならreturn 0;
		}
	}

	if(dp[digit][pre_num][type][is_completed] != -1){
		return dp[digit][pre_num][type][is_completed]; //計算済ならreturn
	}

	ll ret = 0;
	ll limit;
	if(type == FULL_MATCH){
		limit = num_array[digit]-1;
	}else{
		limit = 9;
	}

	ll tmp;

	for(int next = 0; next <= limit; next++){
		tmp =  getNUM(pre_num,next);
		ret += recursive(tmp,digit+1,ELSE,is_completed||is_OK(tmp));
	}

	if(type == FULL_MATCH){
		tmp = getNUM(pre_num,num_array[digit]);
		ret += recursive(tmp,digit+1,FULL_MATCH,is_completed||is_OK(tmp));
	}

	return dp[digit][pre_num][type][is_completed] = ret;
}


int main(){

	ll N;
	scanf("%lld",&N);

	if(N <= 5102){
		printf("0\n");
		return 0;
	}

	stack<ll> S;

	//Nを桁別に分解する
	while(N > 0){
		S.push(N%10);
		N /= 10;
	}

	ll index = 0;

	while(!S.empty()){
		num_array[index++] = S.top();
		S.pop();
	}

	length = index;

	for(int digit = 0; digit <= length-1; digit++){
		for(int pre_num = 0; pre_num <= 9999; pre_num++){
			for(int p = 0; p <= 1; p++){
				for(int k = 0; k <= 1; k++){
					dp[digit][pre_num][p][k] = -1;
				}
			}
		}
	}

	printf("%lld\n",recursive(0,0,FULL_MATCH,false));

	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 8840
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using ll=long long;
using vi=vector<int>;
using pii=pair<int,int>;
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define ITR(i,b,e) for(auto i=(b);i!=(e);++i)
#define FORE(x,c) for(auto &x:c)
#define REPF(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define REP(i,n) REPF(i,0,n)
#define REPR(i,n) for(int i=(int)(n);i>=0;--i)
#define SZ(c) ((int)c.size())
#define CONTAIN(c,x) (c.find(x)!=end(c))
#define OUTOFRANGE(y,x,h,w) ((y)<0||(x)<0||(y)>=(h)||(x)>=(w))
#define dump(...)
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    ITR(i,begin(v),end(v))os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    ITR(i,begin(v),end(v)) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}return 0;}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct{template<class T> operator T(){T x;cin>>x;return x;}} IN;
struct before_main_function {
    before_main_function() {
        cin.tie(0);ios::sync_with_stdio(false);
        cout<<setprecision(15)<<fixed;
        #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

string N;
int rec(int i, bool less, int state) {
    if (i == SZ(N)) {
        return (state >= 4) ? 1 : 0;
    }

    int ret = 0;
    if (less) {
        REP(j, 10) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (state == 3 && j == 1) next_state = 2;
                else if (j == 5) next_state = 1;
                else next_state = 0;
            }
            ret += rec(i+1, true, next_state);
        }
    } else {
        REP(j, N[i]-'0'+1) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (state == 3 && j == 1) next_state = 2;
                else if (j == 5) next_state = 1;
                else next_state = 0;
            }
            ret += rec(i+1, j!=(N[i]-'0'), next_state);
        }
    }
    return ret;
}
signed main() {
    cin >> N;
    cout << rec(0, 0, 0) << endl;
    return 0;
}
accuracy: 0.036036036036036036
time_ms: 190
memory_kb: 3228
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using ll=long long;
using vi=vector<int>;
using pii=pair<int,int>;
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define ITR(i,b,e) for(auto i=(b);i!=(e);++i)
#define FORE(x,c) for(auto &x:c)
#define REPF(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define REP(i,n) REPF(i,0,n)
#define REPR(i,n) for(int i=(int)(n);i>=0;--i)
#define SZ(c) ((int)c.size())
#define CONTAIN(c,x) (c.find(x)!=end(c))
#define OUTOFRANGE(y,x,h,w) ((y)<0||(x)<0||(y)>=(h)||(x)>=(w))
#define dump(...)
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    ITR(i,begin(v),end(v))os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    ITR(i,begin(v),end(v)) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}return 0;}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct{template<class T> operator T(){T x;cin>>x;return x;}} IN;
struct before_main_function {
    before_main_function() {
        cin.tie(0);ios::sync_with_stdio(false);
        cout<<setprecision(15)<<fixed;
        #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

string N;
int rec(int i, bool less, int state) {
    if (i == SZ(N)) {
        return (state >= 4) ? 1 : 0;
    }

    int ret = 0;
    if (less) {
        REP(j, 10) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (state == 3 && j == 1) {
                    next_state = 2;
                } else {
                    if (j == 5) next_state = 1;
                    else next_state = 0;
                }
            }
            ret += rec(i+1, true, next_state);
        }
    } else {
        REP(j, N[i]-'0'+1) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (state == 3 && j == 1) {
                    next_state = 2;
                } else {
                    if (j == 5) next_state = 1;
                    else next_state = 0;
                }
            }
            ret += rec(i+1, j!=(N[i]-'0'), next_state);
        }
    }
    return ret;
}
signed main() {
    cin >> N;
    cout << rec(0, 0, 0) << endl;
    return 0;
}
accuracy: 0.036036036036036036
time_ms: 200
memory_kb: 3228
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using ll=long long;
using vi=vector<int>;
using pii=pair<int,int>;
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define ITR(i,b,e) for(auto i=(b);i!=(e);++i)
#define FORE(x,c) for(auto &x:c)
#define REPF(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define REP(i,n) REPF(i,0,n)
#define REPR(i,n) for(int i=(int)(n);i>=0;--i)
#define SZ(c) ((int)c.size())
#define CONTAIN(c,x) (c.find(x)!=end(c))
#define OUTOFRANGE(y,x,h,w) ((y)<0||(x)<0||(y)>=(h)||(x)>=(w))
#define dump(...)
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    ITR(i,begin(v),end(v))os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    ITR(i,begin(v),end(v)) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}return 0;}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct{template<class T> operator T(){T x;cin>>x;return x;}} IN;
struct before_main_function {
    before_main_function() {
        cin.tie(0);ios::sync_with_stdio(false);
        cout<<setprecision(15)<<fixed;
        #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

string N;
int rec(int i, bool less, int state) {
    if (i == SZ(N)) {
        return (state >= 4) ? 1 : 0;
    }

    int ret = 0;
    if (less) {
        REP(j, 10) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (j == 5) next_state = 1;
                else {
                    if (state == 3 && j == 1) next_state = 2;
                    else next_state = 0;
                }
            }
            ret += rec(i+1, true, next_state);
        }
    } else {
        REP(j, N[i]-'0'+1) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (j == 5) next_state = 1;
                else {
                    if (state == 3 && j == 1) next_state = 2;
                    else next_state = 0;
                }
            }
            ret += rec(i+1, j!=(N[i]-'0'), next_state);
        }
    }
    return ret;
}
signed main() {
    cin >> N;
    cout << rec(0, 0, 0) << endl;
    return 0;
}
accuracy: 0.036036036036036036
time_ms: 180
memory_kb: 3184
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using ll=long long;
using vi=vector<int>;
using pii=pair<int,int>;
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define ITR(i,b,e) for(auto i=(b);i!=(e);++i)
#define FORE(x,c) for(auto &x:c)
#define REPF(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define REP(i,n) REPF(i,0,n)
#define REPR(i,n) for(int i=(int)(n);i>=0;--i)
#define SZ(c) ((int)c.size())
#define CONTAIN(c,x) (c.find(x)!=end(c))
#define OUTOFRANGE(y,x,h,w) ((y)<0||(x)<0||(y)>=(h)||(x)>=(w))
#define dump(...)
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    ITR(i,begin(v),end(v))os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    ITR(i,begin(v),end(v)) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}return 0;}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct{template<class T> operator T(){T x;cin>>x;return x;}} IN;
struct before_main_function {
    before_main_function() {
        cin.tie(0);ios::sync_with_stdio(false);
        cout<<setprecision(15)<<fixed;
        #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

string N;
int rec(int i, bool less, int state) {
    if (i == SZ(N)) {
        return state >= 4;
    }

    int ret = 0;
    if (less) {
        REP(j, 10) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (j == 5) next_state = 1;
                else next_state = 0;
            }
            ret += rec(i+1, true, next_state);
        }
    } else {
        REP(j, N[i]-'0'+1) {
            int next_state = state;
            if ((state == 0 && j == 5)
             || (state == 1 && j == 1)
             || (state == 2)
             || (state == 3 && j == 3)
             || (state >= 4)) next_state++;
            else {
                if (j == 5) next_state = 1;
                else next_state = 0;
            }
            ret += rec(i+1, j!=(N[i]-'0'), next_state);
        }
    }
    return ret;
}
signed main() {
    cin >> N;
    cout << rec(0, 0, 0) << endl;
    return 0;
}
accuracy: 0.036036036036036036
time_ms: 150
memory_kb: 3172
final_rank: 15

code_snippet: //dp[桁][mod 10000][prefixがNと一致しているか][ごちうさ数だと確定したか] = 個数すれば良い。
//一見、dp[桁][51?3のうち何文字とマッチしたか？][(同様なので略)]でできそうに見えるが、マッチしなかったときの遷移が、これだけでは一意に定まらないので
//できない。例えば、(N=999999で) 515153をチェックするとき「515」までマッチするが次の「1」でマッチしない。しかし、次は「51」までマッチした状態から始める必要がある。
//一方で、513153をチェックするとき「515」までマッチするが次の「5」でマッチしない。この場合は、次は「ノーマッチ」の状態から始める必要がある。(↑と状態を同一視できないことが分かる。）

#include <iostream>
#include <string>
#define rep(i, n) for (i = 0; i < n; i++)
#define int long long
using namespace std;

bool check(int x) { if (x / 1000 == 5 && (x % 1000) / 100 == 1 && x % 10 == 3) return true; return false; }
string s;
int dp[19][10000][2][2];

signed main() {
	int i, j, k, l, m;
	
	cin >> s;
	dp[0][0][1][0] = 1;
	
	rep(i, s.length()) {
		rep(j, 10000) {
			rep(k, 2) {
				rep(l, 2) {
					rep(m, 10) {
						if (k == 1 && m > s[i] - '0') break;
						dp[i + 1][(j * 10 + m) % 10000][k && (m == s[i] - '0')][l || check((j * 10 + m) % 10000)] += dp[i][j][k][l];
					}
				}
			}
		}
	}
	
	int ans = 0;
	rep(j, 10000) rep(k, 2) ans += dp[s.length()][j][k][1];
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 8820
final_rank: 6

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <unordered_map>
using namespace std;

#define REP(i, s) for (int i = 0; i < s; ++i)
#define ALL(v) (v.begin(), v.end())
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ EACH(it, P) { s << "<" << *it << "> "; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s << endl; }



string N;
long long dp[21][10010][3][3]; // digit, last4, clear, smaller

bool judge(int n) {
  if ( (n/100) != 51) return false;
  if (n % 10 != 3) return false;
  return true;
}

int main() {
  while (cin >> N) {
	memset(dp, 0, sizeof(dp));
	dp[0][0][0][0] = 1;
	for (int i = 0; i <= N.size(); ++i) {
	  for (int j = 0; j <= 9999; ++j) {
		for (int k = 0; k < 10; ++k) {
		  int nj = (j % 1000) * 10 + k;

		  // smaller -> smaller
		  {
			// clear -> clear
			dp[i+1][nj][1][1] += dp[i][j][1][1];

			// nonclear -> 
			if (judge(nj)) dp[i+1][nj][1][1] += dp[i][j][0][1];
			else dp[i+1][nj][0][1] += dp[i][j][0][1];
		  }

		  // same -> smaller
		  if (k < (int)(N[i] - '0')) {
			// clear -> clear
			dp[i+1][nj][1][1] += dp[i][j][1][0];

			// nonclear ->
			if (judge(nj)) dp[i+1][nj][1][1] += dp[i][j][0][0];
			else dp[i+1][nj][0][1] += dp[i][j][0][0];
		  }

		  // same -> same
		  if (k == (int)(N[i] - '0')) {
			// clear -> clear
			dp[i+1][nj][1][0] += dp[i][j][1][0];

			// nonclear ->
			if (judge(nj)) dp[i+1][nj][1][0] += dp[i][j][0][0];
			else dp[i+1][nj][0][0] += dp[i][j][0][0];
		  }
		  
		}
	  }
	}

	long long res = 0;
	for (int j = 0; j <= 9999; ++j) {
	  for (int smaller = 0; smaller < 2; ++smaller) {
		res += dp[N.size()][j][1][smaller];
	  }
	}

	cout << res << endl;
  }
}
accuracy: 1
time_ms: 20
memory_kb: 18004
final_rank: 10