$dp$。
记$dp[i]$表示$gcd$为$i$的倍数的子序列的方案数。然后倒着推一遍减去倍数的方案数就可以得到想要的答案了。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <algorithm> using namespace std; int n; long long b[100010]; long long a[100010]; long long mod = 1e9+7; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); for(int j=1;j*j<=x;j++) { if(x%j!=0) continue; a[j]++; if(x/j!=j) a[x/j]++; } } b[0]=1; for(int i=1;i<=100000;i++) b[i] = (b[i-1]*2)%mod; for(int i=1;i<=100000;i++) { a[i] = (b[a[i]]-1+mod)%mod; } for(int i=100000;i>=1;i--) { int tmp = i; tmp=tmp+i; while(tmp<=100000) { a[i] = (a[i]- a[tmp]+mod)%mod; tmp=tmp+i; } } printf("%lld ",a[1]); return 0; }