数位dp

数位dp学习笔记

  • 用途:用来解决与数位有关而与数字的值无关或没有太大关系的一类问题。
  • 特征:
    1. 统计满足一定条件的数的数量
    2. 条件转化后可以用数位(数位,指一个数中每一个数字所占的位置)理解判断
    3. 数字范围有限制且很大,暴力验证超时
  • 有一个模板,\(come\quad from\) 一位大佬Mathison,可以解决大部分的数位dp题。
  • 本文只讲例题和思路
  1. [ZJOI2010] 数字计数

    \(solution:\)

    发现很难在一次搜索中将所有答案统计出来,那么就分开统计。\(dp\)式子为

    \[f[p][aim][have][limit][zero] = \sum_{i = 0}^{max} f[p+1][aim][have+(i==aim\quad and\quad(!zero||i))][limit || (i<a[p])][zero\quad and \quad i==0] \]

    \(p\)表示当前填到了第\(p\)

    \(aim\)表示本次搜索所需要统计的数字

    \(have\)表示已经有了\(have\)个数字

    \(limit\)表示是否到达上界 \(true\)为没有

    \(zero\)表示是否有前导\(0\) \(true\)为有

    搜索即可

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define int long long
    const int N = 15;
    ll L,R,sum[N],f[N][N][N][N][N];
    int a[N],len;
    int dfs(int p,int aim,int have,bool limit,bool zero){
        if(p > len) return have;
        if(~f[p][aim][have][limit][zero]) return f[p][aim][have][limit][zero];
        int res = 0,mx = limit?9:a[p];
        for(int i = 0;i <= mx; ++i){
            res += dfs(p+1,aim,have+(i==aim&&(!zero||i)),limit||(i<a[p]),zero&&i==0);
        }
        return f[p][aim][have][limit][zero]=res;
    }
    inline void solve(int x,int sgn){
        memset(f,-1,sizeof f);
        len = 0;
        while(x) a[++len] = x%10,x /= 10;
        reverse(a+1,a+1+len);
        for(int i = 0;i <= 9; ++i){
            sum[i] += sgn*dfs(1,i,0,0,1);
        }
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        read(L,R);
        solve(R,1);solve(L-1,-1);
        for(int i = 0;i <= 9; ++i){
            write(sum[i],' ');
        }
    }
    
  2. [SCOI2009]windy数

    \(solution:\)

    \[f[p][pre][zero][limit] = \sum_{i = 0}^{max}[|i-pre|>1]f[p+1][zero\quad and\quad i==0?-2:i][zero\quad and\quad i==0][limit\quad and\quad i==max] \]

    \(pre\)指上一位填的数

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    const int N = 20;
    int a[N],len;
    ll f[N][10][2][2];
    ll dfs(int p,int pre,bool zero,bool limit){
        if(p > len) return 1;
        if(~f[p][pre][zero][limit]) return f[p][pre][zero][limit];
        ll res = 0,mx = limit ? a[p] : 9;
        for(int i = 0;i <= mx; ++i){
            if(abs(i-pre) < 2) continue;
            if(zero && i == 0) res += dfs(p+1,-2,1,limit && i == mx);
            else res += dfs(p+1,i,0,limit && i == mx);
        }
        return res;
    }
    inline ll solve(ll x){
        len = 0;
        while(x) a[++len] = x%10,x /= 10;
        reverse(a + 1,a + 1 + len);
        memset(f,-1,sizeof f);
        return dfs(1,-2,1,1);
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        ll L,R;read(L,R);
        write(solve(R)-solve(L-1));
    }
    
    
  3. 花神的数论题

    \(solution:\)

    太水了,懒得说了,自己看代码

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define int long long
    const int N = 100,mod = 10000007;
    ll n;
    int len,a[N],sum[N];
    inline int power(int a,int b,int mod){
        int res = 1;
        while(b){
            if(b&1) res = 1ll*res*a%mod;
            a = 1ll*a*a%mod;
            b >>= 1;
        }
        return res;
    }
    ll f[N][N][N][2];
    int dfs(int p,int aim,int have,bool limit){
        if(have > aim) return 0;
        if(p > len) return have == aim;
        if(~f[p][aim][have][limit]) return f[p][aim][have][limit];
        int res = 0,mx = limit?a[p]:1;
        for(int i = 0;i <= mx; ++i)
            res += dfs(p+1,aim,have+(i==1),limit&&i == a[p]);
        return f[p][aim][have][limit] = res;
    }
    inline int solve(int x){
        len = 0;
        while(x) a[++len] = x&1,x >>= 1;
        reverse(a+1,a+1+len);
        memset(f,-1,sizeof f);
        ll ans  = 1;
        for(int i = 1;i <= 50; ++i){
            ans = ans * power(i,dfs(1,i,0,1),mod)%mod;
        }
        return ans;
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        read(n);
        write(solve(n));
    }
    
  4. [CQOI2016] 手机号码

    \(solution:\)

    记录一下前两位数字是多少,是否有3个相邻的连续数字,是否有8,是否有4。

    注意特判\(\le10^{10}\)时直接为0。

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    using namespace __gnu_pbds;
    using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define int long long
    int L,R;
    int len,num[20];
    int f[11][11][11][2][2][2][2];//当前位数,位数+1是,位数+2是,是否有连续,U8,U4,限制
    int dfs(int pos,int a,int b,bool pd,bool _8,bool _4,bool limit){
        if(_4 && _8) return 0;
        if(pos <= 0) return pd;
        if(~f[pos][a][b][pd][_8][_4][limit]) return f[pos][a][b][pd][_8][_4][limit];
        int res = 0,mx = !limit?num[pos]:9;
        for(int i = 0;i <= mx; ++i) 
            res += dfs(pos-1,i,a,pd||(i == a && i == b),_8||(i == 8),_4||(i == 4),i < mx || limit);
        return f[pos][a][b][pd][_8][_4][limit] = res;
    }
    inline int solve(int x){
        if(x < 1e10) return 0;
        len = 0;
        while(x) num[++len] = x%10,x /= 10;
        int res = 0;
        memset(f,-1,sizeof f);
        for(int i = 1;i <= num[len]; ++i)
            res += dfs(10,i,0,0,i == 8,i == 4,i < num[len]);
        return res;
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        int L,R;
        read(L,R);
        write(solve(R)-solve(L-1));
    }
    
  5. [USACO06NOV] Round Numbers S

    \(solution:\) ……

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define int long long
    const int N = 40;
    int f[N][N][N][2][2];
    int a[N],len;
    int dfs(int p,int sum0,int sum1,bool limit,bool is0){
        if(!p) return sum0 >= sum1;
        if(~f[p][sum0][sum1][limit][is0]) return f[p][sum0][sum1][limit][is0];
        int res = 0,mx = limit?a[p]:1;
        for(int i = 0;i <= mx; ++i)
            res += dfs(p - 1,sum0 + ((i == 0)&(!is0)),sum1 + (i == 1),limit & (i == a[p]),is0 & (i == 0));
        return f[p][sum0][sum1][limit][is0] = res;
    }
    inline int solve(int x){
        len = 0;
        while(x) a[++len] = x&1,x >>= 1;
        memset(f,-1,sizeof f);
        return dfs(len,0,0,1,1);
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        int L,R;
        read(L,R);
        // cout<<solve(R)<<' '<<solve(L-1)<<'\n';
        write(solve(R)-solve(L-1));
    }
    
  6. [CL-13]CTH:谁帮我切开这个蛋糕???

    \(solution:\)

    压根就不是数位dp题
    dp式子:

    \[f[i] = \begin{cases} &\sum_{j=i+1}^{n}f[i]\quad s[i] == '1'\\ &f[i+1]\quad other\quad cases \end{cases}\]

    这是\(O(n^2)\)的,过不了,但我们可以用前缀和优化到\(O(n)\)

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define int long long
    const int N = 1e7+10,mod = 998244353;
    char s[N];
    int n;
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        read(n);read(s+1);
        int ans = 1,f = 1;
        for(int i = n;i >= 1; --i){
            if(s[i] == '1') ans = f;
            f += ans;
            f %= 998244353;
        }
        write(ans%998244353);
    }
    
  7. [AHOI2009] 同类分布

    \(solution:\)

    枚举数字之和,记为\(s\)

    记录当前的数字和\(sum\) 和 当前的数 mod s

    当sum = s && 余数为0时,做出1的贡献

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    using namespace __gnu_pbds;
    using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define int long long
    int L,R;
    ll f[20][200][200];
    int len,a[20],mod;
    ll dfs(int pos,int sum,ll st,int limit){
        if(pos > len && sum == 0) return 0;
        if(pos > len) return st == 0 && sum == mod ?1:0;
        if(!limit && f[pos][sum][st] != -1) return f[pos][sum][st];
        ll ret = 0;
        int res = limit ? a[len-pos+1]:9;
        for(int i = 0;i <= res; ++i)
            ret += dfs(pos+1,sum+i,(st*10ll+i)%mod,i == res && limit);
        return limit?ret:f[pos][sum][st] = ret;
    }
    inline ll part(int x){
        len = 0;
        while(x) a[++len] = x%10,x /= 10;
        ll res = 0;
        for(mod = 1;mod <= 9*len; ++mod){
            memset(f,-1,sizeof f);
            res += dfs(1,0,0,1);
        }
        return res;
    }
    inline void solve(){
        while(read(L,R)) write(part(R)-part(L-1),'\n');
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        solve();
    }
    
  8. Beautiful numbers

    \(solution:\)

    首先有个结论,对于\(n\)个数 \(a_{1...n}\)​,设它们的\(LCM\)\(L\),那么对于每个\(i\) 和一个自然数\(x\),
    \(x\equiv x\,mod\,L\pmod{a_i}\)

    然后记录已经填好的各个位数的\(LCM\)

    因为非2520的余数的\(LCM\)对答案无贡献,所以可以把它们与0归为一起。

    预处理即可

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
        template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
        inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
        inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
        inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
        inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
        inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
        inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
        template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
        template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
        inline void write(char x){pc(x);}
        inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
        inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
        template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    const int N = 20;
    #define int long long
    int a[N],len,mp[2521],tot;
    int f[N][2520][50];
    inline int lcm(int a,int b){return a*b/__gcd(a,b);}
    int dfs(int p,int s,int mod,bool limit){
        if(!p) return (s % mod == 0);
        if(!limit && f[p][s][mp[mod]] != -1) return f[p][s][mp[mod]];
        int res = 0,mx = limit ? a[p] : 9;
        for(int i = 0;i <= mx; ++i)
            res += dfs(p - 1,(s * 10 + i) % 2520,(i == 0) ? mod : lcm(mod,i),limit && (i == mx));
        return limit ? res : f[p][s][mp[mod]] = res;
    }
    inline int solve(int x){
        len = 0;
        while(x) a[++len] = x%10,x /= 10;
        return dfs(len,0,1,1);
    }
    signed main(){
        #ifndef ONLINE_JUDGE
            infile("in.in");outfile("out.out");
        #else
        #endif
        for(int i = 1;i <= 2520; ++i)
            if(2520 % i == 0) mp[i] = ++tot;
        memset(f,-1,sizeof f);
        int T;
        read(T);
        while(T--){
            int L,R;read(L,R);
            write(solve(R)-solve(L-1),'\n');
        }
    }
    
  9. 苍与红的试炼

    题意:
    给定两个数\(d,s\,(d\le 500\,s\le 5000)\),求出最小的自然数\(x\),使得\(d|x\)并且\(x\)各位数字的和为\(s\),若不存在,输出\(-1\)

    \(solution:\)

    状态非常好设计,一维为当前已经填入的数字的和,一维为\(mod\,d\)的余数。

    但因为没有位数限制,所以dfs会爆栈。

    故使用bfs

    \(code:\)

    点此查看代码
    #include<bits/stdc++.h>
    #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    // using namespace __gnu_cxx;
    using namespace std;
    #define infile(x) freopen(x,"r",stdin)
    #define outfile(x) freopen(x,"w",stdout)
    #define errfile(x) freopen(x,"w",stderr)
    using ll=long long;using ull=unsigned long long;
    char *p1,*p2,buf[1<<20];
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    #ifdef linux
    #define pc putchar_unlocked
    #else
    #define pc putchar
    #endif
    namespace IO{
    	template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}
    	inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
    	inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
    	inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}
    	inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}
    	inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}
    	inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}
    	inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}
    	inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}
    	template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}
    	template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}
    	inline void write(char x){pc(x);}
    	inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}
    	inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
    	inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}
    	template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
    }using namespace IO;
    #define mk make_pair
    int d,s,cnt,dep;
    bitset<510> vis[5010];
    int pre[5010*510];
    char ans[5010*510];
    void print(int x){
    	if(x == 1) return;
    	print(pre[x]);
    	pc(ans[x]);
    }
    queue<pair<int,int> > q;//first is mod ,second is sum
    inline void bfs(){
    	q.push(mk(0,0));
    	vis[0][0] = true;
    	cnt++;
    	while(!q.empty()){
    		int sum = q.front().first,mod = q.front().second;
    		q.pop(),++dep;
    		for(int i = 0;i <= 9; ++i){
    			int sm = sum + i,md = (mod*10+i)%d;
    			if(sm > s) break;
    			if(vis[sm][md]) continue;
    			++cnt;
    			if(sm == s && !md){
    				pre[cnt] = dep;
    				ans[cnt] = i + '0';
    				print(cnt);
    				return;
    			}
    			vis[sm][md] = 1;
    			q.push(mk(sm,md));
    			pre[cnt] = dep;
    			ans[cnt] = i + '0';
    		}
    	}
    	puts("-1");
    }
    signed main(){
    	#ifndef ONLINE_JUDGE
    		infile("in.in");outfile("out.out");errfile("err.err");
    	#else
    	#endif
    	read(d,s);
    	bfs();
    }
    
    

\(To\,Be\,Continued\)

posted @ 2024-07-02 17:41  CuFeO4  阅读(12)  评论(0编辑  收藏  举报