zoukankan      html  css  js  c++  java
  • hdu3501

    要我们求小于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[n]],      (a[i]表示与n互素的数字)

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

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

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

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

    数据太大,要用long long

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <algorithm>
     5 #include <iostream>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <string>
    12 #include <math.h>
    13 using namespace std;
    14 #pragma warning(disable:4996)
    15 typedef  long long  LL;                   
    16 const int INF = 1<<30;
    17 /*
    18 
    19 */
    20 
    21 
    22 int euler(int n)
    23 {
    24     int m = sqrt(n) + 0.5;
    25     int ans = n;
    26     for (int i = 2; i <= m; ++i)
    27     if (n%i == 0)
    28     {
    29         ans = ans / i * (i - 1);
    30         while (n%i == 0) n /= i;
    31     }
    32     if (n > 1) ans = ans / n *(n - 1);
    33     return ans;
    34 }
    35 int main()
    36 {
    37     
    38     
    39     LL n;
    40     while (scanf("%I64d", &n), n)
    41     {
    42         LL t = euler(n)*n/2;
    43         LL ans = n*(n - 1) / 2 - t;
    44         printf("%I64d
    ", ans % 1000000007);
    45     }
    46     return 0;
    47 }
    View Code
  • 相关阅读:
    html 问题
    bookshelf
    requireJS 用法
    autoprefixer
    移动端 代码块
    D3 学习资源
    折线图
    iscroll 4 下拉 上拉 加载
    iscroll
    重金悬赏的微软:提交Win8漏洞以及发布Win8应用
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4489351.html
Copyright © 2011-2022 走看看