Lucky Number ZOJ - 3233 (容斥)
Lucky Number
题意:给出数组a和b,问区间[L,R]之间有多少个数至少能被数组a中的一个数整除且至少不能被数组b中的一个数整除。
对于数组a,直接容斥
数组b,可以求全都能被乘除的情况,减去就可以了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 ll a[20],b; 5 ll n,m,L,R; 6 7 ll gcd(ll a,ll b){ 8 return b?gcd(b,a%b):a; 9 } 10 ll lcm(ll a,ll b){ 11 if(a/gcd(a,b)>R/b) return R+1; 12 return a/gcd(a,b)*b; 13 } 14 int main(){ 15 while(scanf("%lld%lld%lld%lld",&n,&m,&L,&R)&&(n||m||L||R)){ 16 ll q=1; 17 for(ll i=0;i<n;i++) scanf("%lld",&a[i]); 18 for(ll i=0;i<m;i++) { 19 scanf("%lld",&b); 20 q=lcm(q,b); 21 } 22 ll sta=1<<n; 23 ll cnt=0,ans=0; 24 for(ll i=1;i<sta;i++){ 25 cnt=0; 26 ll temp=1; 27 for(ll j=0;j<n&&temp<=R;j++) if((i>>j)&1) cnt++,temp=lcm(temp,a[j]); 28 if(temp>R) continue; 29 ll s=lcm(q,temp); 30 if(cnt&1) ans+=(R/temp-(L-1)/temp)-(R/s-(L-1)/s); 31 else ans-=(R/temp-(L-1)/temp)-(R/s-(L-1)/s); 32 } 33 printf("%lld\n",ans); 34 } 35 }