POJ Longge's problem 积性函数
2018-02-25 17:36
267 查看
传送门
思路
参考代码
传送门
思路
才学了数论函数又回来看这题,很想知道我以前是怎么过的。。。发现这个数据规模只能强行推导,所以就瞄了一眼以前的代码,就发现了做法。
这个题的正确做法是枚举 gcdgcd,它的时间复杂度为 O(n−−√)O(n)。根据经验,与 nn 的 gcdgcd 为枚举值的个数是 φ(ngcd)φ(ngcd)。求欧拉函数的时间复杂度为 O(n−−√)O(n),所以算法的整体时间复杂度为 O(10n−−√)O(10n),1010 代表质因数个数。
然而另外一个跑得更快的算法是怎么做的,我怎么看不懂了??然后我又研究了下,发现是这样的。
第一个算法的问题,实际上是:
Ans=∑d∣nndφ(d)Ans=∑d∣nndφ(d)
这难道不是一个狄利克雷卷积的形式吗?设答案为 ff:
f=id∗φf=id∗φ 和 φφ 都是积性函数,所以 ff 也是积性函数。我们可以利用积性函数的性质求解 ff。
可得:
f(n)=f(pr11)f(pr22)⋯f(prkk)f(n)=f(p1r1)f(p2r2)⋯f(pkrk)
所以我们只需要知道怎么求 f(pr)f(pr) 就好了。
很明显,当 r=1r=1 时,f(p)=2p−1f(p)=2p−1。当 r≠1r≠1 时,随手写几个找找规律就是了:
f(p5)=p5+p4⋅(p−1)+p3⋅p(p−1)+p2⋅p2(p−1)+p⋅p3(p−1)+p4(p−1)f(p5)=p5+p4⋅(p−1)+p3⋅p(p−1)+p2⋅p2(p−1)+p⋅p3(p−1)+p4(p−1)
时间复杂度为 n−−√n。
参考代码
思路
参考代码
传送门
思路
才学了数论函数又回来看这题,很想知道我以前是怎么过的。。。发现这个数据规模只能强行推导,所以就瞄了一眼以前的代码,就发现了做法。
这个题的正确做法是枚举 gcdgcd,它的时间复杂度为 O(n−−√)O(n)。根据经验,与 nn 的 gcdgcd 为枚举值的个数是 φ(ngcd)φ(ngcd)。求欧拉函数的时间复杂度为 O(n−−√)O(n),所以算法的整体时间复杂度为 O(10n−−√)O(10n),1010 代表质因数个数。
然而另外一个跑得更快的算法是怎么做的,我怎么看不懂了??然后我又研究了下,发现是这样的。
第一个算法的问题,实际上是:
Ans=∑d∣nndφ(d)Ans=∑d∣nndφ(d)
这难道不是一个狄利克雷卷积的形式吗?设答案为 ff:
f=id∗φf=id∗φ 和 φφ 都是积性函数,所以 ff 也是积性函数。我们可以利用积性函数的性质求解 ff。
可得:
f(n)=f(pr11)f(pr22)⋯f(prkk)f(n)=f(p1r1)f(p2r2)⋯f(pkrk)
所以我们只需要知道怎么求 f(pr)f(pr) 就好了。
很明显,当 r=1r=1 时,f(p)=2p−1f(p)=2p−1。当 r≠1r≠1 时,随手写几个找找规律就是了:
f(p5)=p5+p4⋅(p−1)+p3⋅p(p−1)+p2⋅p2(p−1)+p⋅p3(p−1)+p4(p−1)f(p5)=p5+p4⋅(p−1)+p3⋅p(p−1)+p2⋅p2(p−1)+p⋅p3(p−1)+p4(p−1)
时间复杂度为 n−−√n。
参考代码
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <string> #include <stack> #include <queue> #include <deque> #include <map> #include <set> #include <bitset> #include <list> typedef long long INT; using std::cin; using std::cout; using std::endl; INT readIn() { INT a = 0; bool minus = false; char ch = getchar(); while (!(ch == '-' || (ch >= '0' && ch <= '9'))) ch = getchar(); if (ch == '-') { minus = true; ch = getchar(); } while (ch >= '0' && ch <= '9') { a = a * 10 + (ch - '0'); ch = getchar(); } if (minus) a = -a; return a; } void printOut(INT x) { char buffer[20]; INT length = 0; if (x < 0) { putchar('-'); x = -x; } do { buffer[length++] = x % 10 + '0'; x /= 10; } while (x); do { putchar(buffer[--length]); } while (length); putchar('\n'); } long long n; void run() { while (~scanf("%lld", &n)) { //F = id * phi long long f = 1; int to = std::sqrt(n); for (int i = 2; i <= to; i++) { if (n % i) continue; int Exp = 0; long long power = 1; while (!(n % i)) { n /= i; Exp++; power *= i; } power /= i; f *= (long long)Exp * power * (i - 1) + power * i; } if (n) f *= 2 * n - 1; printOut(f); } } int main() { run(); return 0; }
相关文章推荐
- poj 2480 Longge's problem(积性函数 & 欧拉函数)
- poj 2480 Longge's problem(欧拉函数或积性函数)
- POJ 2480 Longge's problem(欧拉函数,积性函数)
- POJ 2480 Longge's problem 解题报告(欧拉函数 + 积性函数)
- POJ 2480 Longge's problem(积性函数之欧拉函数与gcd)
- POJ 2048 Longge's problem (欧拉函数 积性函数)
- POJ 2480 Longge's problem (积性函数,欧拉函数)
- POJ 2480 Longge's problem 欧拉函数的应用 积性函数
- POJ 2480 Longge's problem 欧拉函数
- POJ2480 Longge's problem【乘性函数】
- POJ 2480 Longge's problem(神奇欧拉函数)
- POJ 2480 Longge's problem (欧拉函数)
- POJ 2480 Longge's problem 积性函数
- poj 2480 Longge's problem(欧拉函数的性质)
- POJ2480 Longge's problem 欧拉函数的应用 && 积性函数
- POJ 2480 Longge's problem(数论)
- POJ 2480 Longge's problem
- POJ 2480 Longge's problem 积性函数
- (poj 2480 Longge's problem)<欧拉函数>
- 【poj】 2480 Longge's problem (欧拉函数)