CF803F Coprime Subsequences
Coprime Subsequences
https://ac.nowcoder.com/acm/problem/112055
题意
给定一正整数序列 ,问有多少个非空子序列使得其中所有数的
为 1。
题解
容斥,设 为
为
的倍数,的非空子序列个数。那么如果
中有
个数是
的倍数那么
。
设 为
恰为
的非空子序列个数。那么
。
时间复杂度 ,其中
。
#include <bits/stdc++.h> #define MOD 1000000007 #define REP(temp, init_val, end_val) for (int temp = init_val; temp <= end_val; ++temp) #define REPR(temp, init_val, end_val) for (int temp = init_val; temp >= end_val; --temp) using namespace std; int read(){ int f = 1, x = 0; char c = getchar(); while (c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();} while (c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar(); return f * x; } inline int modadd(int x, int y){ return (x + y >= MOD ? x + y - MOD: x + y); } int poww(int a, int b){ int res = 1; while (b > 0){ if (b & 1) res = 1ll * res * a % MOD; a = 1ll * a * a % MOD, b >>= 1; } return res; } int n, a[100005], cnt[100005] = {0}; int cntb[100005] = {0}; const int m = 100000; int ans[100005]; void init(){ n = read(); REP(i, 1, n) a[i] = read(), ++cnt[a[i]]; REP(i, 1, m) for (int j = i; j <= m; j += i) cntb[i] += cnt[j]; } void solve(){ REPR(i, m, 1){ ans[i] = modadd(poww(2, cntb[i]), MOD - 1); for (int j = i + i; j <= m; j += i) ans[i] = modadd(ans[i], MOD - ans[j]); } printf("%d\n", ans[1]); } int main(){ init(); solve(); return 0; }