3 4 0
0 2
对于给定的n,输出小于n的且不与n互质的正整数的和。
做这道题首先要知道欧拉函数,对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目;而且要知道这样一个结论:如果gcd(n,i)=1,则gcd(n,n-i)=1。知道以上两条结论,这道题的思路就大致清晰了。首先可以知道在[1,n-1]中与n互质的数是成对出现的,即如果i与n互质,则(n-i)一定与n互质。这时我们发现这对于n互质的数的和为n。所以可以得出结论:小于等于n的同时与n互质的数的和是n*Euler(n)/2,Euler(n)表示小于n与n互质的数的个数,同时一对与n互质的数的和为n,这时我们就可以写出公式:n*(小于n与n互质的数的个数)/2,即n*Euler(n)/2(对n是偶数的情况同样成立)。最后只需要计算1到n-1的和,用和减去n*Euler(n)/2。
#include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #pragma commment(linker,"/STACK: 102400000 102400000") #define lson a,b,l,mid,cur<<1 #define rson a,b,mid+1,r,cur<<1|1 using namespace std; typedef long long LL; const double eps=1e-6; const int MAXN=210; LL n; LL Euler(LL n) { LL ans = n; for(LL i = 2; (LL)(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() { while(scanf("%lld",&n)&&n) { printf("%lld\n",(n*(n-1)/2-n*Euler(n)/2)%1000000007); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/noooooorth/article/details/47115155