标签:style class blog code com 2014
题意:给n个数,为有多少互质对;
解法:然后求出mou值,然后求出1,2,3...max的倍数的个数,每个出现在gcd中的对数(num[i]*(num[i]-1))/2,乘上mou值进行容斥计算。
代码:
/****************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 #define zero(_) (abs(_)<=eps) const double pi=acos(-1.0); typedef long long LL; const int Max=222225; const int INF=1000000007; LL num[Max]; LL rem[Max]; int mou[Max]; int n; void init() { for(LL i=2; i<Max; i++) if(!mou[i]) { mou[i]=i; for(LL j=i*i; j<Max; j+=i) mou[j]=i; } mou[1]=1; for(int i=2;i<Max;i++) { if(i/mou[i]%mou[i]==0) mou[i]=0; else { mou[i]=-mou[i/mou[i]]; } } } int main() { init(); while(scanf("%d",&n)==1) { memset(rem,0,sizeof rem); memset(num,0,sizeof num); int ma=0; for(int i=0; i<n; i++) { int a; scanf("%d",&a); ma=max(ma,a); rem[a]++; } ma++; for(int i=1; i<ma; i++) { for(int j=i; j<ma; j+=i) { num[i]+=rem[j]; } } LL ans=0; for(int i=1; i<ma; i++) { ans+=mou[i]*(num[i]*(num[i]-1))/2; } cout<<ans<<'\n'; } return 0; }
ACdreamoj1114(Number theory)莫比乌斯容斥,布布扣,bubuko.com
ACdreamoj1114(Number theory)莫比乌斯容斥
标签:style class blog code com 2014
原文地址:http://blog.csdn.net/xiefubao/article/details/30264689