POJ 2480 Longge's problem 欧拉函数

2024-04-23 19:48

本文主要是介绍POJ 2480 Longge's problem 欧拉函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.

题解:

公式:f(N)=∑x*φ(N/x),x | N (x是N的约数)
因为在1···N中,gcd(i,N) = x, 的个数的等于φ(N / x)

另外还可以利用函数的积性:

对于正整数n的一个函数 f(n),当中f(1)=1且当a,b互质,f(ab)=f(a)f(b),在数论上就称它为积性函数。若某函数f(n)符合f(1)=1,且就算a,b不互质,f(ab)=f(a)f(b),则称它为完全积性函数。


不妨令M, N互素
f(M) = ∑d1 * φ(M / d1), d1 | M
f(N) = ∑d2 * φ(N / d2), d2 | N

f(MN) = ∑d * φ(MN / d), d | MN
因为M, N互素,则每个d都可以唯一分解为M中的因子d1, 和N中的因子d2
即d = d1 * d2, d1 | M, d2 | N, d1与d2互素
则d * φ(MN / d) = d1 * d2 * φ(M / d1) * φ(N / d2)
f(MN)中的项与f(M) * f(N)中的项一一对应

解法一:47MS
#include<cstdio>
#include<cstring>
using namespace std;#define MAXN 200000
#define lint __int64
struct Factor { lint b, e; };
Factor f[MAXN]; lint fnum;
lint a[MAXN], p[MAXN], pn;
lint n, ret;void Prime()
{lint i, j; pn = 0;memset(a,0,sizeof(a));for ( i = 2; i < MAXN; i++ ){if ( a[i] == 0 ) p[pn++] = i;for ( j = 0; j < pn && i*p[j] < MAXN && (p[j]<=a[i] || !a[i]); j++ )a[i*p[j]] = p[j];}
}lint Euler ( lint n )
{lint ret = n;for ( int i = 0; p[i] * p[i] <= n; i++ ){if ( n % p[i] == 0 ){ret = ret - ret / p[i];while ( n % p[i] == 0 ) n /= p[i];}}if ( n > 1 )ret = ret - ret / n;return ret;
}void split ( lint n )
{fnum = 0;for ( int i = 0; p[i] * p[i] <= n; i++ ){if ( n % p[i] ) continue;f[fnum].b = p[i]; f[fnum].e = 0;while ( n % p[i] == 0 ){f[fnum].e++;n /= p[i];}fnum++;}if ( n > 1 )f[fnum].b = n, f[fnum++].e = 1;}void DFS ( lint val, int index ) //求n的每一个约数,然后利用欧拉函数
{if ( index == fnum ){ret += Euler(n/val) * val;   //Euler(n/val)的值表示1-n中gcd(n,i)= val的个数return;}for ( lint i = 0, tmp = 1; i <= f[index].e; i++, tmp *= f[index].b )DFS ( val*tmp, index+1 );
}int main()
{Prime();while ( scanf("%I64d",&n) != EOF ){split ( n );ret = 0;DFS ( 1, 0 );printf("%I64d\n",ret);}
}


解法二:利用积性16ms
#include<cstdio>
#include<cstring>
using namespace std;#define MAXN 200000
#define lint __int64
struct Factor { lint b, e, mult; };
Factor f[MAXN]; lint fnum;
lint a[MAXN], p[MAXN], pn;void Prime()
{lint i, j; pn = 0;memset(a,0,sizeof(a));for ( i = 2; i < MAXN; i++ ){if ( a[i] == 0 ) p[pn++] = i;for ( j = 0; j < pn && i*p[j] < MAXN && (p[j]<=a[i] || !a[i]); j++ )a[i*p[j]] = p[j];}
}lint Euler ( lint n )
{lint ret = n;for ( int i = 0; p[i] * p[i] <= n; i++ ){if ( n % p[i] == 0 ){ret = ret - ret / p[i];while ( n % p[i] == 0 ) n /= p[i];}}if ( n > 1 )ret = ret - ret / n;return ret;
}void split ( lint n )
{fnum = 0;for ( int i = 0; p[i] * p[i] <= n; i++ ){if ( n % p[i] ) continue;f[fnum].b = p[i]; f[fnum].e = 0;f[fnum].mult = 1;while ( n % p[i] == 0 ){f[fnum].e++;f[fnum].mult *= p[i];n /= p[i];}fnum++;}if ( n > 1 )f[fnum].b = f[fnum].mult = n, f[fnum++].e = 1;}int main()
{Prime(); lint n;while ( scanf("%I64d",&n) != EOF ){split ( n );lint ret = 1, tmp, sum;for ( int i = 0; i < fnum; i++ ){tmp = 1, sum = Euler(f[i].mult); //所有与f[i].mult互素的数先加起来for ( int j = 1; j <= f[i].e; j++ ){tmp *= f[i].b;sum += Euler(f[i].mult/tmp) * tmp;}ret *= sum;}printf("%I64d\n",ret);}
}


这篇关于POJ 2480 Longge's problem 欧拉函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/929717

相关文章

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

kotlin的函数forEach示例详解

《kotlin的函数forEach示例详解》在Kotlin中,forEach是一个高阶函数,用于遍历集合中的每个元素并对其执行指定的操作,它的核心特点是简洁、函数式,适用于需要遍历集合且无需返回值的场... 目录一、基本用法1️⃣ 遍历集合2️⃣ 遍历数组3️⃣ 遍历 Map二、与 for 循环的区别三、高

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st