[CF 55D] Beautiful Numbers

題目

Volodya是一個很皮的男♂孩。他認爲一個能被它本身的每一位數上的數整除的數是很妙的。咱們先忽略他的想法的正確性(如需證實請百度「神奇海螺」),只回答在l到r之間有多少個很妙的數字。ios

輸入輸出格式git

輸入:總共有t個詢問:ide

第一行:t;學習

接下來t行:每行兩個數l和r。優化

注意:請勿使用%lld讀寫長整型(雖然我也不知道爲何),請優先使用cin(或者是%I64d)。spa

輸出:t行,每行爲一個詢問的答案。翻譯

(引自洛谷的題目翻譯)code

Input
1
1 9
Output
9
Input
1
12 15
Output
2

解說

第一遍:這道題暴力簡直太簡單了,先暴力一遍試試。blog

結果70組數據跑了8個就TLE了。ci

那這種東西怎麼優化?洛谷一搜,臥槽黑題!!!

我慫了,真不是我慫,我一道黑題都沒過過啊,無力承受這種恐怖!

看題解吧。

(仍是選取我認爲說的最清楚的)

 

引自HSFZ_NOI_DIGIT_DP的洛谷博客

等一下,它說這是數位DP模板題?!

哦,一種新的DP啊,那難怪我不會,那就學習到了啊!

我的能力限制,看完思路仍是難以代碼實現,因此照着仙貝的敲了一遍。一遍敲下來也算是理解了。

我A了一道黑題!

代碼

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<vector>
 7 using namespace std;  8 typedef long long ll;  9 #define Mod 2520
10 int cur,a[Mod+3]; 11 ll l,r,f[20][Mod+3][50]; 12 vector<int> dim; 13 int gcd(int x,int y){return x%y?gcd(y,x%y):y;} 14 int getlcm(int x,int y){if(!y)return x;return x/gcd(x,y)*y;} 15 ll dfs(int x,int mode,int lcm,bool op){ 16     if(!x) return mode%lcm==0?1:0; 17     if(!op&&f[x][mode][a[lcm]])return f[x][mode][a[lcm]]; 18     int maxx=op?dim[x]:9; 19     ll ret=0; 20     for(int i=0;i<=maxx;i++)ret+=dfs(x-1,(mode*10+i)%Mod,getlcm(lcm,i),op&(i==maxx)); 21     if(!op)f[x][mode][a[lcm]]=ret; 22     return ret; 23 } 24 ll solve(ll x){ 25  dim.clear(); 26     dim.push_back(-1); 27     ll t=x; 28     while(t) { 29         dim.push_back(t%10); 30         t/=10; 31  } 32     return dfs(dim.size()-1,0,1,1); 33 } 34 int main(){ 35     for(int i=1;i<=Mod;i++)if(Mod%i==0)a[i]=++cur; 36     int t; 37     cin>>t; 38     while(t--){ 39         cin>>l>>r; 40         cout<<solve(r)-solve(l-1)<<endl; 41  } 42     return 0; 43 } 
View Code

 

幸甚至哉,歌以詠志。

相關文章
相關標籤/搜索