marcool 0200 互质二元组 数论

本文介绍了一种高效的算法来统计给定整数数组中所有互质数对的数量。通过预处理和分段统计的方式,该算法能在较大范围内快速得出结果。

题意:给出N个整数A1A2,……,AN,统计满足i<jAiAj互质的二元组(ij)的数量。

对于100%的数据,1 ≤ N ≤ 100000,1 ≤ Ai ≤ 1000000。

 

 

思路: 因为Ai比较小 所以我们用num[i]统计n个数中i的个数

然后先求出 分别以2~1000000为公约数的有多少对

再求出以2~1000000为最大公约数的有多少对

最后用n*(n-1)/2减去总对数

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #define MAXM 1000000
 6 #define MAXN 110000
 7 long long num[MAXM+1];
 8 long long ans[MAXM+1];
 9 int n;
10 void solve()
11 {
12     int i,x;
13     for(x=2;x<=MAXM;x++)
14         for(i=x;i<=MAXM;i+=x)
15             ans[x]+=num[i];
16     for(x=2;x<=MAXM;x++)
17         ans[x]=ans[x]*(ans[x]-1)/2;
18     for(x=MAXM;x>1;x--)
19         for(i=2*x;i<=MAXM;i+=x)
20             ans[x]-=ans[i];
21     long long s=0;
22     for(x=2;x<=MAXM;x++)
23         s+=ans[x];
24     s=(long long)n*(n-1)/2-s;
25     printf("%lld\n",s);
26 }
27         
28 int main()
29 {
30     memset(num,0,sizeof(num));
31     int x,i;
32     scanf("%d",&n);
33     for(i=1;i<=n;i++)
34     {
35         scanf("%d",&x);
36         num[x]++;
37     }
38     solve();
39     return 0;
40 }

 

 

转载于:https://www.cnblogs.com/myoi/archive/2012/07/21/2602610.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值