Description
给定 n 个正整数序列
,每个序列长度为m。
选择至少 1 个序列,在每个被选择的序列中选择一个元素,求出所有被选择的元素的 gcd。
求所有方案的结果之和,答案对 1e9+7 取模。两种方案不同,当且仅当存在至少一个元素,在一种方案中被选择,在另一种中没有。
选择至少 1 个序列,在每个被选择的序列中选择一个元素,求出所有被选择的元素的 gcd。
求所有方案的结果之和,答案对 1e9+7 取模。两种方案不同,当且仅当存在至少一个元素,在一种方案中被选择,在另一种中没有。
Input
第一行,两个正整数n,m。
接下来n 行,每行m 个正整数,第i 行代表序列
。
接下来n 行,每行m 个正整数,第i 行代表序列
Output
第一行,一个整数,代表答案对 1e9+7 取模的结果。
Sample Input
见下发文件
Sample Output
见下发文件
Data Constraint
![](https://img-blog.csdnimg.cn/2022010611324315845.png)
题解
- 由于题解写的比较优秀,我就不口胡了
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 using namespace std; 5 const long long mo=1e9+7,inf=1e5; 6 int n,m; 7 long long a[30][100010],mx,sum[100010][500],num[30][100010],f[100010],ans; 8 int main() 9 { 10 freopen("b.in","r",stdin); 11 freopen("b.out","w",stdout); 12 scanf("%d%d",&n,&m); 13 for (int i=1;i<=n;i++) 14 for (int j=1;j<=m;j++) 15 scanf("%lld",&a[i][j]),mx=max(a[i][j],mx); 16 for (int i=1;i<=inf;i++) 17 for (int j=1,k=sqrt(i);j<=k;j++) 18 if (i%j==0) 19 { 20 sum[i][++sum[i][0]]=j; 21 if (j*j!=i) sum[i][++sum[i][0]]=i/j; 22 } 23 for (int i=1;i<=n;i++) 24 for (int j=1;j<=m;j++) 25 for (int k=1;k<=sum[a[i][j]][0];k++) 26 num[i][sum[a[i][j]][k]]++; 27 for (int i=1;i<=mx;i++) 28 { 29 f[i]=1; 30 for (int j=1;j<=n;j++) f[i]=(f[i]*(num[j][i]+1))%mo; 31 f[i]=(f[i]-1+mo)%mo; 32 } 33 for (int i=mx;i>=1;i--) 34 { 35 for (int j=2;j<=mx/i;j++) f[i]=(f[i]-f[i*j]+mo)%mo; 36 (ans+=f[i]*i%mo)%=mo; 37 } 38 printf("%lld",ans); 39 return 0; 40 }