数位dp
数位dp学习笔记
- 用途:用来解决与数位有关而与数字的值无关或没有太大关系的一类问题。
- 特征:
- 统计满足一定条件的数的数量
- 条件转化后可以用数位(数位,指一个数中每一个数字所占的位置)理解判断
- 数字范围有限制且很大,暴力验证超时
- 有一个模板,\(come\quad from\) 一位大佬Mathison,可以解决大部分的数位dp题。
- 本文只讲例题和思路
-
\(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],' '); } }
-
\(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)); }
-
\(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)); }
-
\(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)); }
-
\(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)); }
-
\(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); }
-
\(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(); }
-
\(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'); } }
-
苍与红的试炼
题意:
给定两个数\(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\)
本文来自博客园,作者:CuFeO4,转载请注明原文链接:https://www.cnblogs.com/hzoi-Cu/p/18277320