[51nod1232]完美数

  如果一个数能够被组成它的各个非0数字整除,则称它是完美数。例如:1-9都是完美数,10,11,12,101都是完美数,但是13就不是完美数(因为13不能被数字3整除)。
  现在给定正整数x,y,求x和y之间(包含x和y的闭区间)共有多少完美数。
 Input
  第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
  第2 - T + 1行:每行2个数,X, Y中间用空格分割。(1 <= X <= Y <= 10^18)
 Output
  输出共T行,对应区间中完美数的数量。

 

 

  1..10的lcm为2520,从1..10里选若干个数的lcm个数只有四十多个。。

  f[i][j][k]表示十进制下长度为i位的数字里,那个数字模2520后的值为j的倍数,数位上各个非0数字的lcm为第k种。

  之后就是正常的数位DP了。

  一开始不会做是因为状态表示得不对...第二维没有考虑倍数...结果统计的复杂度就上天了...

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstdlib>
 8 #define ll long long
 9 #define ull unsigned long long
10 #define ui unsigned int
11 //#define d double
12 #define ld long double
13 const int maxn=404,inf=1002333333;
14 ll f[20][2523][49];
15 int NEXT[2523][10],LCM[2523][10],id[2523],num[233];
16 int i,j,k,n,m,s,t,ans;
17 
18 int ra,fh;char rx;
19 inline int read(){
20     rx=getchar(),ra=0,fh=1;
21     while(rx<'0'&&rx!='-')rx=getchar();
22     if(rx=='-')fh=-1,rx=getchar();
23     while(rx>='0')ra=ra*10+rx-48,rx=getchar();return ra*fh;
24 }
25 
26 inline int gcd(int a,int b){return !b?a:gcd(b,a%b);}
27 inline void pre(){
28     int i,j,tmp=0;
29     memset(f,255,sizeof(f));
30     for(i=1;i<=2520;i++){
31         if(!(2520%i))id[i]=++tmp;
32         LCM[i][0]=LCM[i][1]=i;
33         for(j=2;j<=9;j++)LCM[i][j]=i*j/gcd(i,j);
34     }
35     for(i=0;i<2520;i++)for(j=0;j<=9;j++)NEXT[i][j]=(i*10+j)%2520;
36 }
37 ll dfs(int i,int p,int lcm,bool pr){
38     if(i<0)return !(p%lcm);
39     if(!pr&&f[i][p][id[lcm]]!=-1)return f[i][p][id[lcm]];
40     int mx=!pr?9:num[i];ll tmp=0;
41     for(int j=0;j<=mx;j++)
42         tmp+=dfs(i-1,NEXT[p][j],LCM[lcm][j],pr&&j==mx);
43     if(!pr)f[i][p][id[lcm]]=tmp;
44     return tmp;
45 }
46 inline ll get(ll x){
47     int len=0;while(x)num[len++]=x%10,x/=10;
48     return dfs(len-1,0,1,1);
49 }
50 int main(){
51     pre();ll l,r;
52     for(int t=read();t;t--)
53         scanf("%lld%lld",&l,&r),
54         printf("%lld\n",get(r)-get(l-1));
55 }
View Code

 

posted @ 2016-10-11 14:07  czllgzmzl  阅读(390)  评论(0编辑  收藏  举报