A-无关(relationship)
链接:https://www.nowcoder.com/acm/contest/135/A
来源:牛客网
无关(relationship)
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
若一个集合A内所有的元素都不是正整数N的因数,则称N与集合A无关。
给出一个含有k个元素的集合A={a1,a2,a3,...,ak},求区间[L,R]内与A无关的正整数的个数。
保证A内的元素都是素数。
输入描述:
输入数据共两行:
第一行三个正整数L,R,k,意义如“题目描述”。
第二行k个正整数,描述集合A,保证k个正整数两两不相同。
输出描述:
输出数据共一行:
第一行一个正整数表示区间[L,R]内与集合A无关的正整数的个数
示例1
输入
复制
1 10 4
2 3 5 7
输出
复制
1
示例2
输入
复制
2 10 4
2 3 5 7
输出
复制
0
说明
对于30%的数据:1<=L<=R<=10^6
对于100%的数据:1<=L<=R<=10^18,1<=k<=20,2<=ai<=100
题目意思:给你一个素数集合,然后问你正整数子集[L,R]中有多少个数不能被素数集合中的任何一个元素整除
思路:
代码:
递归写法
#include <iostream>
using namespace std;
typedef long long ll;
ll l,r,k,g,ans;
ll a[25];
ll uc(ll i,ll x){
if(i==k) return x;
else{
return uc(i+1,x) - uc(i+1,x/a[i]);
}
}
int main(){
cin>>l>>r>>k;
for(int i = 0;i<k;i++) cin>>a[i];
cout<<uc(0,r) - uc(0,l-1)<<endl;
}
正常写法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
inline LL read(){
char c=getchar();
LL num=0,f=1;
while (c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c<='9'&&c>='0'){
num=num*10+c-'0';
c=getchar();
}
return num*f;
}
LL n,a[35],L,R,ans,bin[35];
LL gcd(LL a,LL b){
return b?gcd(b,a%b):a;
}
LL lcm(LL a,LL b){
return a/gcd(a,b)*b;
}
int main(){
bin[0]=1;
for (int i=1;i<=30;i++)
bin[i]=bin[i-1]<<1;
L=read();
R=read();
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
sort(a+1,a+n+1);
for (int i=2;i<=n;i++){
bool exi=false;
for (int j=1;j<i;j++)
if (a[i]%a[j]==0){
exi=true;
break;
}
if(exi) swap(a[i],a[n]),i--,n--;
}
ans=R-L+1;
for (int sta=1;sta<bin[n];sta++){
int cnt=0;
LL tmp=1;
bool exi=true;
for (int i=1;i<=n;i++)
if (sta&bin[i-1])
if (R/a[i]>=tmp)
tmp*=a[i],cnt++;
else{
exi=false;
break;
}
if(!exi) continue;
if (cnt&1)
ans-=R/tmp-(L-1)/tmp;
else ans+=R/tmp-(L-1)/tmp;
}
printf("%lld",ans); return 0;
}