题目大意
给你一个长为(n(nleq 10^5))的序列({a_n}),其中(a_ileq 10^5),求有多少个子序列的(gcd=1)。答案对(10^9+7)取模。
题解
设 (f(x)) 表示 (gcd=x) 的子序列的个数,则题目要求 (f(1))。
设 (g(x)) 表示满足 (gcd=kx,kin Z^+) 的子序列的个数。
设在序列中,(x) 的倍数有 (cnt(x)) 个,则 (g(x)=2^{cnt(x)}-1)。
可以发现, (g(n)=sum_{n|d}f(d)) 。
由莫比乌斯反演定理可得 (f(n)=sum_{n|d}mu(frac{d}{n})g(d)) 。
则(Ans=sum mu(d)(2^{cnt(d)}-1)) 。
线性筛出莫比乌斯函数,(O(Nsqrt{N})) 处理 (Cnt(x)) ,再枚举 (d)计算即可。
Code
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
#define RG register int
#define LL long long
template<typename elemType>
inline void Read(elemType &T){
elemType X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
T=(w?-X:X);
}
const LL MOD=1000000007LL;
int Mu[100010],Cnt[100010];
vector<int> Prime;
bool not_Prime[100010];
int N;
LL ex_Pow(LL b,LL n){
LL x=1;
LL Power=b%MOD;
while(n){
if(n&1) x=x*Power%MOD;
Power=Power*Power%MOD;
n>>=1;
}
return x;
}
inline void Get_Mu(int Len){
Mu[1]=1;
not_Prime[1]=1;
int Size=0;
for(RG i=2;i<=Len;i++){
if(!not_Prime[i]){
Prime.push_back(i);
Mu[i]=-1;++Size;
}
for(RG j=0;j<Size;j++){
int mid=Prime[j]*i;
if(mid>Len) break;
not_Prime[mid]=1;
if(i%Prime[j]==0){Mu[i*Prime[j]]=0;break;}
Mu[mid]=-Mu[i];
}
}
return;
}
inline void Divide(int x){
for(RG i=1;i<=sqrt(x);++i){
if(x%i==0) {
if(i==x/i) ++Cnt[i];
else{++Cnt[i];++Cnt[x/i];}
}
}
return;
}
int main(){
Get_Mu(100000);
Read(N);
for(RG i=1;i<=N;++i){
int x;Read(x);
Divide(x);
}
LL Ans=0;
for(RG i=1;i<=100000;++i)
Ans=(Ans+(LL)Mu[i]*(ex_Pow(2,Cnt[i])-1LL))%MOD;
Ans=(Ans+MOD)%MOD;
printf("%I64d
",Ans);
return 0;
}