您的位置:首页 > 其它

hdu3501 Calculation 2

2016-05-12 12:15 197 查看
题目要求的是小于n且与n不互质的数之和。

要我们求小于n并且不与n互素的数字的和, 那么可以转化为1->(n-1)的和减去小于n且与n互素的数字的和

首先,有gcd(n,i)=1, 那么gcd(n,n-i)=1, 这是因为如果a%s=0, b%s=0, 那么(a-b)%s=0

所以gcd(n,i)=1, 那么gcd(n,n-i)=1, 如果gcd(n,n-i)!=1 ,那么 gcd(n,n-(n-i))!=1,所以 如果gcd(n,i)=1,那么gcd(n,n-i)=1成立

下面设小于n且与n素数的数字的和为sum

sum = a[0] + a[1] + a[2] + ... + a[phi
], (a[i]表示与n互素的数字)

sum = (n-a[0]) + (n-a[1]) + (n-a[2])+...+(n-a[phi
])

两个式子相加, 2*sum = phi
*n->sum = phi
*n/2

1->(n-1)的和为n*(n-1)/2

所以最终答案为n*(n-1)/2 - phi
*n/2

数据太大,要用long long

#include <iostream>
#include <cmath>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define mod 1000000007
long long eular(long long n)
{
long long ans=n;
for(int i=2;i*i<=n;i++)
{

if(n%i==0){
ans-=ans/i;
while(n%i==0)
n/=i;
}
}
if(n>1)ans-=ans/n;
return ans;

}
int main()
{
__int64 n;

while(~scanf("%I64d",&n))
{
if(n==0)break;
__int64 x=(n*(n-1)/2-eular(n)*n/2)%mod;
printf("%I64d\n",x);

}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: