首页 > 代码库 > bzoj2705 [SDOI2012]Longge的问题

bzoj2705 [SDOI2012]Longge的问题

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2705

令s(k)为gcd(i, n) = k的i的个数,则ans = k * s(k).

若gcd(i, n) = k,则gcd(i / k, n / k) = 1,所以 s(k) = phi(n / k)。   (如果这里没搞懂,随便举个例子就懂了)

剩下的就是O(√n)枚举n的因数就好了~

#include <cstdio>
#include <cmath>

long long n, ans;
int lmt;

int phi(int x) {
	int rt = x;
	for (int i = 2; i * i <= x; ++i) {
		if (x % i == 0) {
			rt = rt / i * (i - 1);
			x /= i;
			while (x % i == 0) {
				x /= i;
			}
		}
	}
	if (x > 1) {
		rt = rt / x * (x - 1);
	}
	return rt;
}

int main(void) {
	scanf("%lld", &n);
	lmt = (int)sqrt((float)n + 0.5f);
	for (int i = 1; i <= lmt; ++i) {
		if (n % i == 0) {
			ans += (long long)i * (long long)phi(n / i);
			if (n / i != i) {
				ans += (long long)(n / i) * (long long)phi(i);
			}
		}
	}
	printf("%lld\n", ans);
	return 0;
}

  

bzoj2705 [SDOI2012]Longge的问题