結果
| 問題 |
No.2455 Numbers Dictionary
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-09-01 23:55:04 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 110 ms / 2,000 ms |
| コード長 | 5,630 bytes |
| コンパイル時間 | 2,133 ms |
| コンパイル使用メモリ | 202,656 KB |
| 最終ジャッジ日時 | 2025-02-16 17:42:25 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 22 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define overload2(a, b, c, ...) c
#define overload3(a, b, c, d, ...) d
#define overload4(a, b, c, d, e ...) e
#define overload5(a, b, c, d, e, f ...) f
#define overload6(a, b, c, d, e, f, g ...) g
#define fast_io ios::sync_with_stdio(false); cin.tie(nullptr);
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
typedef long long ll;
typedef long double ld;
#define chmin(a,b) a = min(a,b);
#define chmax(a,b) a = max(a,b);
#define bit_count(x) __builtin_popcountll(x)
#define leading_zero_count(x) __builtin_clz(x)
#define trailing_zero_count(x) __builtin_ctz(x)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a / gcd(a,b) * b
#define rep(...) overload3(__VA_ARGS__, rrep, rep1)(__VA_ARGS__)
#define rep1(i,n) for(int i = 0 ; i < n ; i++)
#define rrep(i,a,b) for(int i = a ; i < b ; i++)
#define repi(it,S) for(auto it = S.begin() ; it != S.end() ; it++)
#define pt(a) cout << a << endl;
#define print(...) printall(__VA_ARGS__);
#define debug(a) cout << #a << " " << a << endl;
#define all(a) a.begin(), a.end()
#define endl "\n";
#define v1(T,n,a) vector<T>(n,a)
#define v2(T,n,m,a) vector<vector<T>>(n,v1(T,m,a))
#define v3(T,n,m,k,a) vector<vector<vector<T>>>(n,v2(T,m,k,a))
#define v4(T,n,m,k,l,a) vector<vector<vector<vector<T>>>>(n,v3(T,m,k,l,a))
template<typename T,typename U>istream &operator>>(istream&is,pair<T,U>&p){is>>p.first>>p.second;return is;}
template<typename T,typename U>ostream &operator<<(ostream&os,const pair<T,U>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T>istream &operator>>(istream&is,vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T>ostream &operator<<(ostream&os,const vector<T>&v){for(auto it=v.begin();it!=v.end();){os<<*it<<((++it)!=v.end()?" ":"");}return os;}
template<typename T>istream &operator>>(istream&is,vector<vector<T>>&v){for(T &in:v){is>>in;}return is;}
template<typename T>ostream &operator<<(ostream&os,const vector<vector<T>>&v){for(auto it=v.begin();it!=v.end();){os<<*it<<((++it)!=v.end()?"\n":"");}return os;}
template<typename T>ostream &operator<<(ostream&os,const set<T>&v){for(auto it=v.begin();it!=v.end();){os<<*it<<((++it)!=v.end()?" ":"");}return os;}
template<typename T>ostream &operator<<(ostream&os,const multiset<T>&v){for(auto it=v.begin();it!=v.end();){os<<*it<<((++it)!=v.end()?" ":"");}return os;}
template<class... Args> void printall(Args... args){for(auto i:initializer_list<common_type_t<Args...>>{args...}) cout<<i<<" ";cout<<endl;}
string S ; // 入力されるめちゃでかい値
string K;
ll dp[20][2][3][21] ; // i桁目にsmallerでkな値
//---------------------------------------------------------------------------//
// debug //
//---------------------------------------------------------------------------//
// cout << "dp[" << i+1 << "][0][" << t << "] = " << dp[i+1][0][t] << endl ; //
// cout << "dp[" << i+1 << "][1][" << t << "] = " << dp[i+1][1][t] << endl ; //
//---------------------------------------------------------------------------//
void solve(){
memset(dp,0,sizeof(dp));
cin >> S >> K ;
int n = S.size() ;
int k = K.size();
vector<int> digit, target ; // 各桁の値
rep(i,n){
// 各桁の値を入れていく
digit.push_back(S[i] - '0') ;
}
rep(i,k){
target.push_back(K[i] - '0') ;
}
// 初期化を忘れない
dp[0][0][1][0] = 1 ;
rep(i,n){
// Leading 0 がある場合
{
if(i > 0) {
rrep(x,1,10){
if(target[0] == x) dp[i+1][1][1][1] += 1;
if(target[0] > x) dp[i+1][1][2][20] += 1;
}
}
}
// smaller が 0 の場合の処理
{
int xxxx , oooo ;
// 次の桁を見る
{
if(i < k && digit[i] < target[i]){
dp[i+1][0][2][20] += dp[i][0][1][i] ;
}
if(i < k && digit[i] == target[i]){
dp[i+1][0][1][i+1] += dp[i][0][1][i] ;
}
dp[i+1][0][2][20] += dp[i][0][2][20];
// Leading 0 では上から0桁目に関しては次の桁の値は0としては行けない(03543のような値を作ってしまうため)
// 1桁目以降は次の桁の値の候補として0~9までどれを入れても良い(1桁目が決まっていれば103843のようになる)
int fir = 0 ;
if(i == 0) fir = 1 ;
rrep(x,fir,digit[i]){
if(i < k && target[i] == x) dp[i+1][1][1][i+1] += dp[i][0][1][i];
if(i < k && target[i] > x) dp[i+1][1][2][20] += dp[i][0][1][i];
dp[i+1][1][2][20] += dp[i][0][2][20];
}
}
}
// smaller が 1 の場合の処理
{
int xxxx, oooo ;
// smaller == trueの状態から遷移する
// 自由に遷移して良いので問題によっては対称性を利用することも可能
rep(x,10) rep(dg,k){
if(target[dg] == x) dp[i+1][1][1][dg+1] += dp[i][1][1][dg];
if(target[dg] > x) dp[i+1][1][2][20] += dp[i][1][1][dg];
}
dp[i+1][1][2][20] += dp[i][1][2][20] * 10;
}
}
ll res = dp[n][0][2][20] + dp[n][1][2][20];
rep(i,k) res += dp[n][1][1][i] + dp[n][0][0][i];
pt(res+1)
}
int main(){
fast_io
int t = 1;
cin >> t;
rep(i,t) solve();
}