标签:幸运 == 很多 content hint -- namespace logs string
【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
题解:显然由6和8组成的数一共也没有多少个,我们可以先将这些数全部枚举出来。然后自然想到容斥,总数=能被一个数整除的-能被2个数整除的+能被3个数整除的。。。。
然后试了一下,极限数据跑得奇慢无比。于是看题解,发现需要先把那些数中能相互整除的去掉,并且枚举顺序要改成从大到小,这技巧也是神了~
#include <cstring> #include <iostream> #include <cstdio> #include <algorithm> using namespace std; typedef long long ll; ll v[3000],w[3000]; ll L,R,ans; int n,m; void init(ll now) { if(now>R) return ; if(now) w[++m]=now; init(now*10+6),init(now*10+8); } ll gcd(ll a,ll b) { return (!b)?a:gcd(b,a%b); } void dfs(int x,ll now,int f) { if(x>n) return ; for(int i=x;i<=n;i++) { ll g=gcd(now,v[i]); if(R/(v[i]/g)/now-L/(v[i]/g)/now) { ll tmp=v[i]*now/g; ans+=f*(R/tmp-L/tmp),dfs(i+1,tmp,-f); } } } int main() { scanf("%lld%lld",&L,&R),L--; init(0); sort(w+1,w+m+1); int i,j; for(i=1;i<=m;i++) if(w[i]!=-1) for(j=i+1;j<=m;j++) if(w[j]%w[i]==0) w[j]=-1; for(i=m;i>=1;i--) if(w[i]!=-1) v[++n]=w[i]; dfs(1,1,1); printf("%lld",ans); return 0; }//1 10000000000
【BZOJ1853/2393】[Scoi2010]幸运数字/Cirno的完美算数教室 DFS+容斥
标签:幸运 == 很多 content hint -- namespace logs string
原文地址:http://www.cnblogs.com/CQzhangyu/p/7468750.html