zoukankan      html  css  js  c++  java
  • hdu 3501 容斥原理或欧拉函数

    Calculation 2

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2181    Accepted Submission(s): 920


    Problem Description
    Given a positive integer N, your task is to calculate the sum of the positive integers less than N which are not coprime to N. A is said to be coprime to B if A, B share no common positive divisors except 1.
     
    Input
    For each test case, there is a line containing a positive integer N(1 ≤ N ≤ 1000000000). A line containing a single 0 follows the last test case.
     
    Output
    For each test case, you should print the sum module 1000000007 in a line.
     
    Sample Input
    3 4 0
     
    Sample Output
    0 2
     
    Author
    GTmac
     
    Source
     
    题目大意:给一个数n求1到n-1之间与它不互质的数之和mod(1000000007)。
    解题思路:我首先想到的是把n质因数分解成n=a1^p1*a2^p2....*an^pn的形式,那么把与他含有共同因子的数之和算出来,这里面有重复的,所以用容斥原理计算。
    一个数的欧拉函数phi(n),根据gcd(n,i)==1,gcd(n,n-i)==1,所以与n互质的数都是成对出现的(他们的和等于n)。
     
     1 //欧拉函数
     2 #include <stdio.h>
     3 #include <math.h>
     4 
     5 typedef __int64 LL;
     6 const int Mod=1000000007;
     7 
     8 LL euler_phi(LL n)
     9 {
    10     LL m=(LL)sqrt(n*1.0);
    11     LL ans=n;
    12     for(int i=2;i<=m;i++) if(n%i==0)
    13     {
    14         ans=ans/i*(i-1);
    15         while(n%i==0) n/=i;
    16     }
    17     if(n>1) ans=ans/n*(n-1);
    18     return ans;
    19 }
    20 
    21 int main()
    22 {
    23     LL n;
    24     while(~scanf("%I64d",&n),n)
    25     {
    26         LL phi=euler_phi(n);
    27         LL t1=(n*phi/2)%Mod;
    28         LL t2=(n*(n+1)/2-n)%Mod;
    29         LL ans=(t2-t1+Mod)%Mod;
    30         printf("%I64d
    ",ans);
    31     }
    32     return 0;
    33 }
     1 //容斥原理
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <math.h>
     5 
     6 typedef __int64 LL;
     7 const int Mod=1000000007;
     8 const int maxn=100000;
     9 bool flag[maxn];
    10 int prime[maxn],num,n;
    11 int factor[100],cnt;
    12 bool vis[100];
    13 LL ans,temp;
    14 
    15 void get_prime()
    16 {
    17     num=0;memset(flag,true,sizeof(flag));
    18     for(int i=2;i<maxn;i++)
    19     {
    20         if(flag[i]) prime[num++]=i;
    21         for(int j=0;j<num&&prime[j]*i<maxn;j++)
    22         {
    23             flag[i*prime[j]]=false;
    24             if(i%prime[j]==0) break;
    25         }
    26     }
    27 }
    28 
    29 void get_factor()
    30 {
    31     cnt=0;
    32     int i,top=(int)sqrt(n*1.0),t=n;
    33     for(i=0;i<num && prime[i]<=top;i++)
    34     {
    35         if(t%prime[i]==0)
    36         {
    37             factor[cnt++]=prime[i];
    38             while(t%prime[i]==0)
    39                 t/=prime[i];
    40         }
    41     }
    42     if(t>1) factor[cnt++]=t;
    43 }
    44 
    45 void dfs(int now,int top,int start,LL s)
    46 {
    47     if(now==top)
    48     {
    49         LL t=(n-1)/s;
    50         LL a=((t+1)*t/2)%Mod;
    51         LL b=(a*s)%Mod;
    52         temp=(temp+b)%Mod;
    53         return ;
    54     }
    55     for(int j=start;j<cnt;j++)
    56     {
    57         if(!vis[j])
    58         {
    59             vis[j]=true;
    60             dfs(now+1,top,j+1,s*factor[j]);
    61             vis[j]=false;
    62         }
    63     }
    64     return ;
    65 }
    66 
    67 void solve()
    68 {
    69     ans=0;
    70     int c=1;
    71     for(int i=1;i<=cnt;i++)
    72     {
    73         memset(vis,false,sizeof(vis));
    74         temp=0;dfs(0,i,0,1);
    75         ans=(((ans+c*temp)%Mod)+Mod)%Mod;
    76         c=-c;
    77     }
    78 }
    79 
    80 int main()
    81 {
    82     get_prime();
    83     while(scanf("%d",&n),n)
    84     {
    85         get_factor();
    86         solve();
    87         printf("%I64d
    ",ans);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    假设用一个名为text的字符串向量存放文本文件的数据,其中的元素或者是一句话或者是一个用于表示段分隔的空字符串。将text中第一段全改为大写形式
    迭代器介绍
    从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写字母。
    标准库类型vector
    css 滤镜之AlphaImageLoader
    css设置背景图片自适应
    网易云音乐怎么免费下载付费歌曲
    font-family,font-size,color
    css设置图片居中、居左、居右
    数据库语句之建表、拷贝数据表
  • 原文地址:https://www.cnblogs.com/xiong-/p/3949617.html
Copyright © 2011-2022 走看看