BZOJ 2705 [SDOI2012]Longge的问题【Euler变形】

来源:互联网 发布:网络搭建方案 编辑:程序博客网 时间:2024/06/05 16:06

2705: [SDOI2012]Longge的问题

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 2418  Solved: 1474
[Submit][Status][Discuss]

Description

Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。

Input

一个整数,为N。

Output

一个整数,为所求的答案。

Sample Input

6

Sample Output

15

HINT

【数据范围】

对于60%的数据,0<N<=2^16。

对于100%的数据,0<N<=2^32。

 



思路:如果直接遍历数据大不行,那就找出N的所有因子,这样就变少了,如果 GCD(i,N)=K,->GCD(i/K,N/K)=1(GCD(a,b)==1优先考虑欧拉,反之成立), 对于一个因子对区间产生的影响就是区间内有多少数和N的最大因子是K,经过上述转化就成求N/K的欧拉函数了,直接上模板就行,求出欧拉函数后乘以K,就是因子K产生的影响,求所有因子之和就行了,由于N的因子在<=sqrt(N)的确定,就可以优化一下,对于i*i==N还需特判;

失误:有点思路但不清晰,知道从因子入手,还是差一点。


AC代码:

#include<cstdio>typedef long long LL;LL Euler(LL N){int i=0,eu=N;for(i=2;i*i<=N;++i){if(N%i==0){eu=eu/i*(i-1);while(N%i==0) N/=i;}}if(N>1) eu=eu/N*(N-1);return eu;}int main(){LL N,i;while(~scanf("%lld",&N)){LL ans=0;for(i=1;i*i<N;++i){if(N%i==0){ans=ans+i*Euler(N/i)+N/i*Euler(i); }  }  if(i*i==N) { ans+=i*Euler(i);  } printf("%lld\n",ans);}return 0; } 

 

0 0
原创粉丝点击