標籤:int mes swa case sse typedef queue 個數 bool
題意:一個數能整除它所有的位上的數字(除了0),統計這樣數的個數。
注意離散化,為了速度更快需存入數組尋找。
不要每次memset,記錄下已有的長度下合格個數。
數位dp肯定是從高位到低位。
記錄數字已經有多大,還有lcm,遞迴傳下去。
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <iomanip>#include <cstring>#include <map>#include <queue>#include <set>#include <cassert>using namespace std;const double EPS=1e-8;const int SZ=5050,INF=0x7FFFFFFF;typedef long long lon;lon dp[20][3000][50],index[3000];//2520vector<lon> ls;lon gcd(lon x,lon y){ if(x<y)swap(x,y); for(;;) { lon rem=x%y; if(rem==0)return y; x=y; y=rem; }}lon lcm(lon x,lon y){ return x*y/gcd(x,y);}void getid(){ for(lon i=0;i<ls.size();++i) { index[ls[i]]=i; }}void lsh(){ for(lon i=1;i<pow(2,10);++i) { lon cur=1; for(lon j=0;j<9;++j) { if(i&(1<<j))cur=lcm(cur,j+1); } ls.push_back(cur); } sort(ls.begin(),ls.end()); ls.erase(unique(ls.begin(),ls.end()),ls.end()); getid();}lon dfs(lon pos,lon cur,lon prelcm,lon limit,string &str){ if(pos==str.size())return cur%prelcm==0; if(!limit&&dp[str.size()-pos-1][cur][index[prelcm]]!=-1)return dp[str.size()-pos-1][cur][index[prelcm]]; lon res=0; lon up=limit?str[pos]-‘0‘:9; for(lon i=0;i<=up;++i) { lon curlcm=prelcm; if(i)curlcm=lcm(i,curlcm); res+=dfs(pos+1,(cur*10+i)%2520,curlcm,limit&&str[pos]-‘0‘==i,str); } if(!limit)dp[str.size()-pos-1][cur][index[prelcm]]=res; return res;}lon work(string &str){ return dfs(0,0,1,1,str);}bool chk(string &str){ lon num=0,curlcm=1; for(lon i=0;i<str.size();++i) { num=(num*10+str[i]-‘0‘)%2520; if(str[i]!=‘0‘)curlcm=lcm(curlcm,str[i]-‘0‘); } return num%curlcm==0;}int main(){ std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); lon casenum; cin>>casenum; lsh(); memset(dp,-1,sizeof(dp)); for(lon time=1;time<=casenum;++time) { string ll,rr; cin>>ll>>rr; lon res=work(rr)-work(ll); if(chk(ll))++res; cout<<res<<endl; } return 0;}
codeforces 55d//Beautiful numbers// Codeforces Beta Round #51