[bzoj1853]幸运数字
容易发现幸运数字只有1024个,暴力标记倍数还是会tle的
容斥,即从中任选i个的lcm,复杂度为$o(2^1024)$
剪枝一:当答案超过1024就不用算了
剪枝二:当某个数是另一个数的倍数时就删掉
(另外求lcm可能会爆long long,由于爆了long long一定不合法,因此可以用除法来判定)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 ll x,y,ans,a[10005]; 5 ll gcd(ll x,ll y){ 6 if (!y)return x; 7 return gcd(y,x%y); 8 } 9 void tot(ll k){ 10 if (k>y)return; 11 if (k)a[++a[0]]=k; 12 tot(k*10+6); 13 tot(k*10+8); 14 } 15 void dfs(int k,int s,ll val){ 16 if (k>a[0]){ 17 ans+=(y/val-(x-1)/val)*(s*2-1); 18 return; 19 } 20 dfs(k+1,s,val); 21 ll g=val/gcd(val,a[k]); 22 if (g<=y/a[k])dfs(k+1,s^1,a[k]*g); 23 } 24 int main(){ 25 scanf("%lld%lld",&x,&y); 26 tot(0); 27 sort(a+1,a+a[0]+1); 28 for(int i=a[0];i;i--) 29 for(int j=1;j<i;j++) 30 if (a[i]%a[j]==0)a[i]=0; 31 sort(a+1,a+a[0]+1); 32 for(int i=1;i<=a[0]/2;i++)swap(a[i],a[a[0]-i+1]); 33 while (!a[a[0]])a[0]--; 34 dfs(1,0,1); 35 printf("%lld",ans+(y-x+1)); 36 }