题目大意:

求  1(m)到n直接有多少个数字x满足 x可以整出这个数字的每一位上的数字

思路:

整除每一位。只需要整除每一位的lcm即可

但是数字太大,dp状态怎么表示呢

发现 1~9的LCM 是2520 ....也就是说只要对这个数mod2520 剩下的余数能整除lcm就可以整除了。。

计数的时候还有一个技巧,具体见注释

此外这个题还卡常数了,预处理lcm才过了。。

代码如下:

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define LCM 2520
long long dp[][LCM+][][];
long long n;
int m;
int state[],hs[],s;
bool vi[];
int d[];
int Lcm[][];
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int lcm(int a,int b)
{
if(b==)
return a;
return a/gcd(a,b)*b;
} void ini()
{
m=;
while(n)
{
d[++m]=n%;
n/=;
}
reverse(d+,d+m+);
}
void DP()
{
memset(dp,,sizeof(dp));
//先放最高位
for(int i=;i<d[];i++)
{
dp[][i][hs[i]][]=; //dp...[0]存储的是前i位的数小于所求数的方案
}
dp[][d[]][hs[d[]]][]=; //dp...[1]存储的是前i位的数等于所求数的方案
//从高位往下转移
for(int i=;i<=m;++i)
{
for(int j=;j<;++j)
dp[i][j][hs[j]][]=; //从大于1的数位开始放1~9都肯定小于所求数
for(int j=;j<;++j)
{
for(int k=;k<s;++k)
{
if(dp[i-][j][k][]==&&dp[i-][j][k][]==)
continue;
for(int t=;t<=;++t)
{
int sum=(j*+t)%LCM;
int L=Lcm[k][t];
dp[i][sum][hs[L]][]+=dp[i-][j][k][]; //在当前位放的数小于等于所求数的当前为数的情况可以继承高位都等于所求数的方案
//否则,只能继承高位小于所求数的方案
if(t<d[i]) //当前位放的数小于所求数的当前位
{
dp[i][sum][hs[L]][]+=dp[i-][j][k][];
}
if(t==d[i]) //当前位放的数等于所求数的当前位
{
dp[i][sum][hs[L]][]+=dp[i-][j][k][];
} }
}
}
}
}
void setstate()
{
memset(vi,,sizeof(vi));
s=;
int tmp;
for(int i=;i<(<<);i++)
{
tmp=;
for(int j=;j<;j++)
{
if((<<j)&i)
{
tmp=lcm(j+,tmp);
}
}
if(vi[tmp]==)
{
state[s]=tmp;
hs[tmp]=s++;
vi[tmp]=;
}
}
for(int i=;i<s;i++)
{
for(int j=;j<=;j++)
Lcm[i][j]=lcm(state[i],j);
}
}
long long cal()
{
long long ans=; for(int i=;i<;i++)
{
for(int j=;j<s;j++)
{
if(i%state[j]==)
ans+=dp[m][i][j][]+dp[m][i][j][];
}
}
return ans;
}
long long solve(long long x)
{
n=x;
ini();
DP();
return cal();
}
int main()
{
long long a,b;
setstate();
int t;
scanf("%d",&t);
while(t--)
{
//scanf("%I64d%I64d",&a,&b);
scanf("%I64d",&a);
//cout<<solve(b)-solve(a-1)<<endl;
cout<<solve(a)<<endl;
}
return ;
}

最新文章

  1. vue.js 第五课
  2. javascript code snippet -- Forwarding Mouse Events Through Layers
  3. MyEclipse生成WAR包并在Tomcat下部署发布(转发)
  4. Storm可靠性实例解析——ack机制
  5. Android Studio通过JNI调用NDK程序
  6. Android EditText的设置
  7. POJ 3253 Fence Repair(修篱笆)
  8. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化
  9. poj 1141 动态规划进行括号匹配
  10. 在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型
  11. 字符串(多串后缀自动机):HDU 4436 str2int
  12. WebService(2)-XML系列之Java和Xml之间相互转换
  13. Android学习笔记-TextView(文本框)(二)
  14. javascript中slice() splice() concat()操作数组的方法
  15. RunLoop已入门?赶紧来应用一下
  16. ExtJS学习(一)Ext自定义类实现
  17. 解决 VS2017 打断点无效
  18. css:pointer-events: none
  19. slideDown留言板
  20. css样式表之边框

热门文章

  1. &#183;数据库基本内容回顾-day16.06.30
  2. html移动端开发注意事项
  3. tortoisegit 保存用户名密码
  4. Blade和其他构建工具有什么不同
  5. ExecuteNonQuary接收存储过程的输出类型的变量的值
  6. Web Api学习一
  7. 限制窗口拉伸范围(二)——OnSizing
  8. STL 之 vector 用法
  9. 数据库触发器new old
  10. [转载] HDFS and Erasure Codes (HDFS-RAID)