[题解]CF55D Beautiful Numbers
打出暴搜后有些茫然,不知道该怎么优化才好,看了题解才豁然开朗。
简单说下暴搜的思路:参数有\(pos,limit,lcm,num\)。其中\(lcm\)表示到\(pos+1\)位,所有非\(0\)位的\(lcm\)是多少;\(num\)表示填到\(pos+1\)位的整个数是多少。然后在\(pos=0\)时判断\(lcm\)是否整除\(num\),是则返回\(1\),否则返回\(0\),然后一层层累加。
优化思路其实很简单:
显然直接用\(f[pos][num][lcm]\)来记忆化,无论时间还是空间都是过不去的。
但我们知道所有非\(0\)位整除\(num\),就等价于它们的\(lcm\)整除\(num\)。
我们想知道\(num\)是否被\(2\)整除,那么我们关注它\(mod\ 2\)的值是否为\(0\);
我们想知道\(num\)是否被\(6\)整除,那么我们关注它\(mod\ 6\)的值是否为\(0\)。
……
那么我们想知道\(num\)是否被\(a_1,a_2,…,a_k\)整除,那么我们只需要关注它\(mod\ lcm\{a_1,a_2,…,a_k\}\)的值是否为\(0\)。
那么我们只需要记录\(num\ mod\ lcm\{1,2,…,9\}\)的值即\(num\ mod\ 2520\)即可。
\(f[pos][num][lcm]\)空间共\(20*2520*2520\)。而250MB的空间限制还是不允许我们开那么大。怎么继续优化呢?
注意到\(lcm\)中我们能用到的一共就那么几个。我们知道\(2520\)一共有\(48\)个因数。而我们\(1\sim 9\)能凑出的数的个数肯定比\(48\)少了。因此我们把质因数离散化一下,第三维开\(50\)绰绰有余。
我的代码和离散化的意思差不多,大概是现读现存的感觉,用map
存下来每个质因数存在哪个位置上。
update on 2024/11/28:比起使用map
之类,还是更建议提前预处理,否则常数较大,容易被卡。
(不知道为什么用了unsigned long long
,其实不需要)
点击查看代码
#include<bits/stdc++.h> #define int unsigned long long using namespace std; int t,l,r,a[30],f[30][2520][50]; bool vis[30][2520][50]; map<int,int> ma; int val[50],cnt; int __lcm(int a,int b){ return a/__gcd(a,b)*b; } int dfs(int pos,bool limit,int lcm,int num){ if(pos==0){ if(num%lcm==0) return 1; return 0; } if(!limit&&ma.find(lcm)!=ma.end()&&vis[pos][num][ma[lcm]]) return f[pos][num][ma[lcm]]; int rig=limit?a[pos]:9,ans=0; for(int i=0;i<=rig;i++){ ans+=dfs(pos-1,limit&&i==rig,i?__lcm(lcm,i):lcm,(num*10+i)%2520); } if(!limit){ if(ma.find(lcm)==ma.end()) ma[lcm]=++cnt,val[cnt]=lcm; f[pos][num][ma[lcm]]=ans,vis[pos][num][ma[lcm]]=1; } return ans; } int solve(int x){ int len=0; while(x){ a[++len]=x%10; x/=10; } return dfs(len,1,1,0); } signed main(){ cin>>t; memset(vis,0,sizeof vis); while(t--){ cin>>l>>r; cout<<solve(r)-solve(l-1)<<endl; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效