hdu5212Code 容斥原理

//给一个数列a求segma(gcd(ai , aj)*(gcd(ai,aj) - 1))
//运用容斥原理,对于以x为倍数的数的个数为k
//那么以k为最大公约数的个数为f[x] = k^2 - f[2*x] - f[3*x] .....
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std ;
const int mod = 10007 ;
const int maxn = 10010 ;
int a[maxn] ;
int f[maxn] ;
void dfs(int pos)
{
    int ans = 0 ;
    int sum = a[pos] ;
    for(int i = 2*pos;i < maxn;i+=pos)
    {
        if(!f[i])
        dfs(i) ;
        f[pos] -= f[i] ;
        sum += a[i] ;
    }
    f[pos] += sum*sum ;
}
int main()
{
    //freopen("in.txt" ,"r",stdin) ;
    int n ;
    while(~scanf("%d" , &n))
    {
        memset(a , 0 ,sizeof(a)) ;
        memset(f , 0 , sizeof(f)) ;
        int t ;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d" , &t) ;
            a[t]++ ;
        }
       int ans = 0 ;
       for(int i = 2;i < maxn ;i++)
       {
           if(!f[i])
           dfs(i) ;
           ans = (ans + ((f[i]*i)%mod)*(i - 1))%mod  ;
       }
       printf("%d\n" , (ans+mod)%mod) ;
    }
    return 0 ;
}



你可能感兴趣的:(hdu5212Code 容斥原理)