[SCOI2010]幸运数字
很简单的容斥题。考场上想出正解,然后写挂了。死因:实现方法想多了。
就很简单,枚举所有幸运号码(可以证出大概两千个),把有倍数关系的提取出来删掉大的,这样肯定不会影响答案,然后做容斥即可。实现过程直接爆搜即可,甚至不用剪枝,因为这些数毕竟有那么大,几次lcm之后就可以顺利地超过1e10.要注意的是lcm的过程可能会爆龙龙宝宝,要判一下。没什么了。
倒序之后是跑得更快,但不倒序也可以卡过,时间上倒是有8倍差距。
#include<bits/stdc++.h>
//#define feyn
#define int long long
const int N=10010;
const int maxn=1e18;
const int S=1e12;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w>='0'&&w<='9'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int l,r,a[N],num;
void find(int wh){
if(wh>r)return;
if(wh)a[++num]=wh;
find(wh*10+6);find(wh*10+8);
}
inline int gcd(int s1,int s2){
return s2==0?s1:gcd(s2,s1%s2);
}
inline int lcm(int s1,int s2){
if(s1>maxn/s2)return S;
return s1/gcd(s1,s2)*s2;
}
int ans;
void dfs(int wh,int val,int c){
if(val>1&&val<=r)ans+=c*(r/val-l/val);
if(wh>num||val>r)return;
for(int i=wh;i<=num;i++){
dfs(i+1,lcm(val,a[i]),-c);
}
}
inline bool cmp(int s1,int s2){
return s1>s2;
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(l);read(r);find(0);l--;
sort(a+1,a+num+1);
int ss=0;
for(int i=1;i<=num;i++){
if(a[i]==0)continue;
a[++ss]=a[i];
for(int j=i+1;j<=num;j++){
if(a[j]%a[i]==0)a[j]=0;
}
}
num=ss;
sort(a+1,a+num+1,cmp);
dfs(1,1,-1);
printf("%lld",ans);
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具