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

2010 ACM-ICPC Multi-University Training Contest(7)——Host by HIT

题目大意:给一个数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\n",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\n",ans);
88     }
89     return 0;
90 }
时间: 2024-12-18 02:17:14

hdu 3501 容斥原理或欧拉函数的相关文章

hdu 3501 Calculation 2 (欧拉函数)

题目 题意:求小于n并且 和n不互质的数的总和. 思路:求小于n并且与n互质的数的和为:n*phi[n]/2 . 若a和n互质,n-a必定也和n互质(a<n).也就是说num必定为偶数.其中互质的数成对存在.其和为n. 公式证明: 反证法:如果存在K!=1使gcd(n,n-i)=k,那么(n-i)%k==0而n%k=0那么必须保证i%k=0k是n的因子,如果i%k=0那么gcd(n,i)=k,矛盾出现; 所以先求出1--n-1 的和, 再用这个和 减去 上面公式求出来的值. 欧拉函数phi(m)

HDU 3501 Calculation 2(欧拉函数的应用)

HDU 3501 Calculation 2 大意:求1~n之间与n不互质的数的总和. 思路:欧拉函数的应用:先用欧拉函数求出与n互质的总数m,计算m个数的总和,用n的总和减去m的总和就是想要的结果. 1 #include <stdio.h> 2 #define LL __int64 3 4 int eular(int n){ 5 int ret = 1; 6 for(int i = 2; i*i <= n;i++) 7 if(n%i == 0){ 8 n /= i, ret *= i-

HDU 3501 Calculation 2 (欧拉函数应用)

Calculation 2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2989    Accepted Submission(s): 1234 Problem Description Given a positive integer N, your task is to calculate the sum of the posit

hdu 2814 快速求欧拉函数

1 /** 2 大意: 求[a,b] 之间 phi(a) + phi(a+1)...+ phi(b): 3 思路: 快速求欧拉函数 4 **/ 5 6 #include <iostream> 7 #include <cstring> 8 using namespace std; 9 #define Max 3000000 10 11 long long phi[Max+5]; 12 int prime[Max/10]; 13 bool flag[Max+5]; 14 15 void

HDU 1695 GCD(欧拉函数+容斥原理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:x位于区间[a, b],y位于区间[c, d],求满足GCD(x, y) = k的(x, y)有多少组,不考虑顺序. 思路:a = c = 1简化了问题,原问题可以转化为在[1, b/k]和[1, d/k]这两个区间各取一个数,组成的数对是互质的数量,不考虑顺序.我们让d > b,我们枚举区间[1, d/k]的数i作为二元组的第二位,因为不考虑顺序我们考虑第一位的值时,只用考虑小于i的情

hdu 1695 GCD (欧拉函数、容斥原理)

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7357    Accepted Submission(s): 2698 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y

hdu 1695 GCD【欧拉函数+容斥原理】

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6253    Accepted Submission(s): 2291 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y

HDU 5430 Reflect(欧拉函数)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=5430 从镜面材质的圆上一点发出一道光线反射NNN次后首次回到起点. 问本质不同的发射的方案数. 输入描述 第一行一个整数T,表示数据组数.T≤10T \leq 10T≤10 对于每一个组,共一行,包含一个整数,表示正整数N(1≤N≤106)N(1 \leq N \leq 10^{6})N(1≤N≤10?6??). 输出描述 对于每一个组,输出共一行,包含一个整数,表示答案. 输入样例 1 4 输出样例

容斥原理、欧拉函数、phi

容斥原理: 直接摘用百度词条: 也可表示为 设S为有限集, ,则 两个集合的容斥关系公式:A∪B = A+B - A∩B (∩:重合的部分) 三个集合的容斥关系公式:A∪B∪C = A+B+C - A∩B - B∩C - C∩A +A∩B∩C 详细推理如下: 1. 等式右边改造 = {[(A+B - A∩B)+C - B∩C] - C∩A }+ A∩B∩C 2.文氏图分块标记如右图图:1245构成A,2356构成B,4567构成C 3.等式右边()里指的是下图的1+2+3+4+5+6六部分: 那