題目
http://codeforces.com/contest/585/problem/E
分析
題目太神QAQ。
考慮選出一個非空集合
假設有
設
則有
那麼答案應該是
我們已經知道了
但是很難求,還是考慮容斥
選出一個數和
考慮
不妨計算選出一個數使得
那麼答案爲不選k的倍數
考慮
設
其中
而
代碼很簡練
#include <bits/stdc++.h>
#define maxn 10000010
using namespace std;
int n, a[maxn], h[maxn];
int mu[maxn], p[maxn], primes;
bool vis[maxn];
const int N = maxn - 10;
const long long mod = 1e9 + 7;
long long pow2[maxn];
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &a[i]), h[a[i]] ++;
long long t;
mu[1] = 1;
for(int i = 2; i <= N; i ++){
if(!vis[i]){p[primes ++] = i; mu[i] = -1;}
for(int j = 0; j < primes; j ++){
if((long long)p[j] * i > N)break;
vis[p[j] * i] = true;
if(i % p[j] == 0){mu[p[j] * i] = 0; break;}
mu[p[j] * i] = -mu[i];
}
}
pow2[0] = 1;
for(int i = 1; i <= N; i ++)pow2[i] = (pow2[i-1] << 1) % mod;
long long Ans = 0;
for(int i = 2; i <= N; i ++){
if(mu[i] == 0)continue;
int c = 0;
for(int j = i; j <= N; j += i)
c += h[j];
if(c == 0)continue;
t = (pow2[c] - 1) * (n - c) % mod;
if(mu[i] == -1)Ans = (Ans + t) % mod;
else Ans = (Ans - t + mod) % mod;
}
printf("%I64d\n", Ans % mod);
return 0;
}