传送门
Description
给出n个数a1,a2……an,求区间[L,R]中有多少个整数不能被其中任何一个数整除。
Input
第一行三个正整数,n,L,R。
第二行n个正整数a1,a2……an
Output
一个数,即区间[L,R]中有多少个整数不能被其中任何一个数整除。
Sample Input
2 1 1000
10 15
Sample Output
867
Data Constraint
对于30%的数据,1<=n<=10,1<=L,R<=1000
对于100%的数据,1<=n<=18,1<=L,R<=10^9
Analysis
我们可以开一个数组Bi表示由i个元素构成的最小公倍数
对于只有一个元素A1时,则B1-1=A1;
当加入第二个元素A2时,则B2-1=lcm(B1-1,A2)=lcm(A1,A2),B1-2=A2;
当加入第三个元素A3时,则B3-1=lcm(B2-1,A3)=lcm(lcm(A1,A2),A3),B2-2=lcm(B1-1,A3)=lcm(A1,A3),B2-3=lcm(B1-2,A3)=lcm(A2,A3)
……以此类推
则每加入一个元素Ai
有:
for(j=i;j>=2;i--)
for(k=1;k<=b[j-1][0];k++) b[j][++b[j][0]]=lcm(b[j-1][k],a[i]);
最后统计答案,注意奇加偶减
Realization
#include<bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
#define fin(x) freopen(""#x".in","r",stdin)
#define fout(x) freopen(""#x".out","w",stdout)
#define open(x) fin(x);fout(x)
#define ll long long
#define inf INT_MAX
ll n,l,r,i,j,k,s,ss,a[19],b[19][100000];
ll gcd(ll a,ll b){
if(b==0) return a;
return gcd(b,a%b);
}
ll lcs(ll a,ll b){
return a*b/gcd(a,b);
}
ll f(ll x){
s=0;
memset(b,0,sizeof(b));
fo(i,1,n){
s+=x/a[i];
fd(j,i,2){
ss=0;
fo(k,1,b[j-1][0]){
b[j][++b[j][0]]=lcs(b[j-1][k],a[i]);
ss+=x/b[j][b[j][0]];
}
if(j%2==0) s-=ss;else s+=ss;
}
b[1][++b[1][0]]=a[i];
}
return s;
}
int main(){
scanf("%lld%lld%lld",&n,&l,&r);
fo(i,1,n) scanf("%lld",&a[i]);
printf("%lld",(r-l+1)-(f(r)-f(l-1)));
}