Lucky Number ZOJ - 3233 (容斥)

Lucky Number

 ZOJ - 3233 

题意:给出数组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 }
View Code

 

posted @ 2017-08-21 11:35  yijiull  阅读(198)  评论(0编辑  收藏  举报