根据要求求除数的数 与 互素和算法 (的品质因数和欧拉函数分解)

Description

One day, Qz met an easy problem. But after a 5-hout-long contest in CSU, he became very tired and he wanted to call his girlfriend as soon as possible. As we all know, Qz is a genius in plenty of fields especially in programming. But he did not want to write a program to solve this problem, he just want to call his girlfriend. Now he gave this problem to you, and he want you to solve this problem without programming. Fortunately, YH heard about Qz’s bad behavior, and he thought that not everyone is as clever as Qz. Finally, YH managed to persuade Qz to ask you to write a program to solve this problem. The problem is:

Qz will give you only one number N (1<= N <= 10^9), and he wants to know the answer of A sub B, A and B are as follow:

A is sum of series of numbers X (He only cares about X which is no larger than N) .For each X, that exists an integer k satisfies that k * X = N.

B is sum of series of numbers Y (He only cares about Y which is no larger than N).For each Y satisfies that GCD(Y, N) = 1.

YH whispers to you that GCD(X, Y) means the Greatest Common Divisor of X and Y, and you should not let Qz know that YH has told you the secret.

Qz is so hurry so he had no time to give you the N one by one and he will give you multiple cases.

YH is so kind and he ask Qz that for each input file, the number of N is about 30000.

Input

Qz is so hurry to call his girlfriend so he has no time to explain the Input.

Output

Help Qz to output the answer to problems on each line.

Sample Input

1
2
3
4

Sample Output

0
2
1
3

题意:给出一个数n , 求n的约数和减去不大于n且与n互质的数的和,记为a-b。

当时去现场做想到的仅仅有暴力,但10^9超时无疑。后来听出题人的解说,说用到欧拉函数,当时也不怎么明确。

直到今天看到一个性质:上述的b有一个公式,b=(n*f(n))/2。

f(n)代表n的欧拉函数。(有关证明在数论书中能够找到)。

问题转化为求n的约数和。n的欧拉函数。都须要用到分解质因数。将n分解为n=p1^a1*p2^a2*...*pn^an。

n的约数和记为S(n),S(n)的公式不再赘述。

大致思路已经有了。先构造根号n的素数表。由于质因数不会超过根号n,然后就是分解质因数的过程。

该题目能够作为求约束和与不大于n且与n互质的和的模板。

#include<stdio.h>
#include<math.h>
typedef unsigned long long LL;
#define maxn 200000
LL primet[maxn];
int pnum = 0;
LL n,a,b,res;
bool flag[maxn];
void getprimtable()//筛法求出素数
{
    for (long i = 2; i < maxn; i++)
        if (!flag[i]) {
            primet[pnum++] = i;
            for (long j = i + i; j < maxn; j += i) flag[j] = true;
        }
}
LL FF(LL x ,LL y) {
    LL ret=1;
    while(y--) ret*=x;
    return ret;
}
LL eularpk(LL p, int k)//欧拉求p^k
{
    if (k == 0) return 1;
    LL ans = p - 1;
    while (--k) ans *= p;
    return ans;
}
LL f(LL n)//求f 因式分解
{
    LL sum = 1;
    res=1;
    int p, k;
    for (int i = 0; primet[i]*primet[i]<= n; i++) {
        p = primet[i];
        if (n % p == 0) {
            k = 0;
            while (n % p == 0) {n /= p; k++;}
            sum = sum * eularpk(p, k);  // p^k
            res*=( ( FF(p,k+1) -1 ) / (p-1));
        }
    }
    if (n > 1) {      // 分解到最后剩下一个素因子 , 须特别注意。
        sum = sum * eularpk(n, 1);
        res*=( ( FF(n,2) -1 ) / (n-1));
    }
    return sum;
}
int main() {
    getprimtable();
    while(~scanf("%lld",&n)) {
        LL b=n*f(n)/2;
        if(n == 1) printf("0\n");
        else printf("%lld\n",res-b);
    }
    return 0;
}



时间: 2024-08-28 16:59:25

根据要求求除数的数 与 互素和算法 (的品质因数和欧拉函数分解)的相关文章

POJ2407---Relatives(求单个数的欧拉函数)

Description Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if there are no integers x > 1, y > 0, z > 0 such that a = xy and b = xz. Input There are several

【欧拉函数】(小于或等于n的数中与n互质的数的数目)

[欧拉函数] 在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler's totient function.φ函数.欧拉商数等. 例如φ(8)=4,因为1,3,5,7均和8互质. 从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明. [证明]: 设A, B, C是跟m, n, mn互质的数的集,据中国剩余定理,A*B和C可建立一一对应的关系.因此φ(n)的值使用算术基本定理便知, 若 n= ∏p^(α(下标p))p|

【数论-欧拉函数】HDU 3501 Calculation 2 ( 与n不互质的数的和 )

[题目链接]click here~ [题目大意]给定整数n,求与n不互质的数的和,最后mod1e9+7 [解题思路]我们利用欧拉函数和欧几里德定理,if  gcd(n,i)==1 ,则有 gcd(n,n-i)==1 ,可以知道 其中一个若为i则存在一个为n-i 那么二者之和为n  ,这样的一共有eular(n)/2对  故与n互质的所有数的和为 n*eular(n)/2 那么与n不互质的 数就是(n)*(n-1)/2-n*eular(n)/2 [source]2010 ACM-ICPC Mult

LIGHT OJ 1370 欧拉函数(在小于自身的正整数中有n个与自身互素的数,这样的数最小的为n后第一个素数)

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include <cmath> 7 using namespace std; 8 typedef long long ll; 9 const ll INF = -100000000000ll; 10 const double ep

欧拉函数 求小于某个数并与其互质的数的个数

1 const int maxn=32790; 2 int euler[maxn+2]; 3 void make() 4 { 5 euler[1]=0; 6 for(int i=2;i<=maxn;++i) 7 euler[i]=i; 8 for(int i=2;i<=maxn;++i) 9 if(euler[i]==i) 10 for(int j=i;j<=maxn;j+=i) 11 euler[j]=euler[j]/i*(i-1); 12 } euler[n]代表的就是在n之前与n

清华集训 2014--奇数国(线段树&amp;欧拉函数&amp;乘法逆元&amp;状态压缩)

昨天想了一晚...早上AC了... 这么长时间没打线段树,这回居然一次过了... 感觉数论方面应该已经没有太大问题了... 之后要开始搞动态规划之类的东西了... 题意 在一片美丽的大陆上有100000个国家,记为1到100000.这里经济发达,有数不尽的账房,并且每个国家有一个银行.某大公司的领袖在这100000个银行开户时都存了3大洋,他惜财如命,因此会不时地派小弟GFS清点一些银行的存款或者让GFS改变某个银行的存款.该村子在财产上的求和运算等同于我们的乘法运算,也就是说领袖开户时的存款总

欧拉项目004:寻找最大的回文数

Problem 4: Largest palindrome product A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers. 寻找有两

回文数系列题目(经典算法)

回文数 时间限制:1000 ms  |  内存限制:65535 KB 难度:0 描述 请寻找并输出1至1000000之间的数m,它满足m.m^2和m^3均为回文数.回文数大家都知道吧,就是各位数字左右对称的整数,例如121.676.123321等.满足上述条件的数如m=11,m^2=121,m^3=1331皆为回文数. 输入 没有输入 输出 输出1至1000000之间满足要求的全部回文数,每两个数之间用空格隔开,每行输出五个数 解析:这道题直接模拟就好了,算是回文数中最简单的题了,直接写个判断回

根据权重随机选取指定条数记录的简单算法实现(C#)

一.应用场景: 有时我们需要从一些列数据中根据权重随机选取指定条数记录出来,这里需要权重.随机,我们根据权重越大的,出现概率越大.例如广告系统:可根据客户支付金额大小来调控客户们的广告出现概率,客户支付金额越大,其广告出现频率越频繁,例如:加入有10条广告,然后每条广告都有一个权重,我们每次要根据权重选取5条广告出来进行显示.有了需求,我们就进行解决,本文章就是利用一种简单的算法来实现根据权重来随机选取. 二.简单算法的实现: 根据我们需求,上网找了不少资料,都没有找到一种比较适合的方案,就自己