Code
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 456 Accepted Submission(s): 182
Problem Description
WLD likes playing with codes.One day he is writing a function.Howerver,his computer breaks down because the function is too powerful.He is very sad.Can you help him?
The function:
int calc
{
int res=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
res+=gcd(a[i],a[j])*(gcd(a[i],a[j])-1);
res%=10007;
}
return res;
}
The function:
int calc
{
int res=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
res+=gcd(a[i],a[j])*(gcd(a[i],a[j])-1);
res%=10007;
}
return res;
}
Input
There are Multiple Cases.(At MOST
10
)
For each case:
The first line contains an integer N(1≤N≤10000) .
The next line contains N integers a1,a2,...,aN(1≤ai≤10000) .
For each case:
The first line contains an integer N(1≤N≤10000) .
The next line contains N integers a1,a2,...,aN(1≤ai≤10000) .
Output
For each case:
Print an integer,denoting what the function returns.
Print an integer,denoting what the function returns.
Sample Input
5 1 3 4 2 4 题目大意: 易懂 题目分析: 因为数据范围很小,所以考虑数据范围内的每一个数作为gcd对于整个结果的贡献, 首先对于x,将它作为gcd的两个数一定都是它的倍数,而它的倍数有k个情况下,最多有k^2种情况将它作为最大公约数, 我们设f[x]是x作为最大公约数的数的对数,那么如果是两个是x倍数的数的最大公约数若不是x,那么一定是x的倍数,所以 f[x]+f[2x]+....+f[tx] = k*k , tx <= 10000 , k为x的倍数的个数 那么f[x]=k*k - sigma[2-t](f[tx]), 所以先筛出每个数的倍数的个数,然后利用公式倒序求取之后,再枚举每一个数,求和即可 复杂度n*sqrt(n)#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #define MAX 10007 #define MOD 10007 using namespace std; int f[MAX]; int n,a; int cnt[MAX]; int main ( ) { while ( ~scanf ( "%d" , &n ) ) { memset ( cnt , 0 , sizeof ( cnt ) ); for ( int i = 1 ; i <= n ; i++ ) { scanf ( "%d" , &a ); for ( int j = 1 ; j*j <= a ; j++ ) if ( a%j == 0 ) { cnt[j]++; if ( a/j != j ) cnt[a/j]++; } } int ans = 0; for ( int x = 10000 ; x > 0 ; x-- ) { f[x] = cnt[x]*cnt[x]%MOD; for ( int i = x*2 ; i <= 10000 ; i += x ) f[x] = ( f[x] - f[i] + MOD) %MOD; int p = x*(x-1)%MOD; ans = ( ans + p*f[x]%MOD )%MOD; } printf ( "%d\n" , ans ); } return 0; }