【bzoj1853】: [Scoi2010]幸运数字 数论-容斥原理
预处理出所有幸运数字然后容斥原理
但是幸运数字是2logn个数的 直接搞会炸
所以把成倍数的处理掉
然后发现还是会T 所以数字要从大到小处理会快很多 我也不知道为什么
还有就是剪枝的时候要开double 不然爆longlong
1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <map> 7 #include <algorithm> 8 using namespace std; 9 #define ll long long 10 11 const ll N=10000000005; 12 ll num[5000]; 13 ll a,b,cnt,ans,cc; 14 15 ll gcd(ll a,ll b){ return b==0 ? a : gcd(b,a%b);} 16 ll lcm(ll a,ll b){ return a/gcd(a,b)*b;} 17 18 void dfs(ll x,ll n){ 19 if (x>n) return; 20 num[++cnt]=x; 21 dfs(x*10+6,n); 22 dfs(x*10+8,n); 23 } 24 25 void rc(ll c,ll x,ll n,ll nw){ 26 if (x==0){ 27 if (c==0) return; 28 if (c&1) ans+=n/nw; else ans-=n/nw; 29 return; 30 } 31 if ((double)nw/gcd(num[x],nw)*num[x] <= n) rc(c+1,x-1,n,lcm(nw,num[x])); 32 rc(c,x-1,n,nw); 33 } 34 35 ll work(ll n){ 36 if (n<6) return 0; 37 cnt=0;ans=0; 38 dfs(6,n);dfs(8,n);cc=cnt; 39 num[0]=1; 40 sort(num+1,num+cnt+1); 41 for (int i=1;i<=cnt;i++){ 42 for (int j=i+1;j<=cnt && num[i]!=N;j++){ 43 if (num[j]%num[i]==0) num[j]=N,cc--; 44 } 45 } 46 sort(num+1,num+cnt+1); 47 rc(1,cc-1,n,num[cc]); 48 rc(0,cc-1,n,1); 49 return ans; 50 } 51 52 int main(){ 53 scanf("%lld%lld",&a,&b); 54 printf("%lld\n",work(b)-work(a-1)); 55 return 0; 56 }