<h2>题目大意</h2>
给长度为 $n$ 的序列,询问有多少个子序列满足它们的 gcd 为 $1$。
<h2>题解</h2>
其实这篇博客是用来 水 的 (强行刷文章量)
我们设 $f(x)$ 表示 $gcd = x$ 的子序列的数量,那么可以立马启发我们设 $F(x)$ 表示 gcd 是 $x$ 的倍数的子序列数量,如果我们统计出 $cnt_i$ 表示 $i$ 和 $i$ 的倍数的数量,那么 $F(x) = 2^{cnt_x} - 1$。
又可以发现 $f(x)$ 和 $F(x)$ 满足关系 $F(x) = \sum_{d|x} f(d)$,也就有 $f(x) = \sum_{x|d} F(d)\mu(d)$,直接暴力算就可以了。。。(甚至不需要任何数论分块技巧,是一道小学组数论题)
/* * Author: RainAir * Time: 2019-08-27 21:31:06 */ #include <algorithm> #include <iostream> #include <cstring> #include <climits> #include <cstdlib> #include <cstdio> #include <bitset> #include <vector> #include <cmath> #include <ctime> #include <queue> #include <stack> #include <map> #include <set> #define fi first #define se second #define U unsigned #define P std::pair #define Re register #define LL long long #define pb push_back #define MP std::make_pair #define all(x) x.begin(),x.end() #define CLR(i,a) memset(i,a,sizeof(i)) #define FOR(i,a,b) for(Re int i = a;i <= b;++i) #define ROF(i,a,b) for(Re int i = a;i >= b;--i) #define DEBUG(x) std::cerr << #x << '=' << x << std::endl #define int LL const int MAXN = 1e5 + 5; const int ha = 1e9 + 7; int prime[MAXN],mu[MAXN],tot; int p[MAXN]; inline void prepare(){ mu[1] = 1; FOR(i,2,MAXN-1){ if(!p[i]) prime[++tot] = i,mu[i] = -1; for(int j = 1;j <= tot && i*prime[j] < MAXN;++j){ p[i*prime[j]] = true; if(!(i%prime[j])){ mu[i*prime[j]] = 0; break; } mu[i*prime[j]] = -mu[i]; } } } inline int qpow(int a,int n){ int res = 1; while(n){ if(n & 1) res = 1llresa%ha; a = 1llaa%ha; n >>= 1; } return res; } int a[MAXN],cnt[MAXN]; int n; signed main(){ scanf("%lld",&n);prepare(); FOR(i,1,n){ int x;scanf("%lld",&x); int q = std::sqrt(1.0*x); FOR(i,1,q){ if(!(x%i)){ cnt[i]++; if(x/i != i) cnt[x/i]++; } } } int ans = 0; FOR(i,1,100000) (ans = (ans+(qpow(2,cnt[i])+ha-1)%ha*mu[i]+ha)%ha); printf("%lldn",ans); return 0; }