HDU 4983 Goffi and GCD(数论)

Posted gccbuaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4983 Goffi and GCD(数论)相关的知识,希望对你有一定的参考价值。

HDU 4983 Goffi and GCD

思路:数论题。假设k为2和n为1。那么仅仅可能1种。其它的k > 2就是0种,那么事实上仅仅要考虑k = 1的情况了。k = 1的时候,枚举n的因子,然后等于求该因子满足的个数,那么gcd(x, n) = 该因子的个数为phi(n / 该因子),然后再利用乘法原理计算就可以

代码:

#include <cstdio>
#include <cstring>
#include <cmath>

typedef long long ll;

const ll MOD = 1000000007;
const int N = 35333;

ll n, k, pn, vis[N];
ll prime[N], frc[N], fn, cnt[N];

void getprime() {
    pn = 0;
    for (ll i = 2; i < N; i++) {
	if (vis[i]) continue;
	prime[pn++] = i;
	for (ll j = i * i; j < N; j += i)
	    vis[j] = 1;
    }
}

void getfrc(ll n) {
    fn = 0;
    for (ll i = 0; i < pn && n >= prime[i]; i++) {
	if (n % prime[i] == 0) {
	    frc[fn] = prime[i];
	    cnt[fn] = 0;
	    while (n % prime[i] == 0) {
		cnt[fn]++;
		n /= prime[i];
	    }
	    fn++;
	}
    }
    if (n != 1) {
	frc[fn] = n;
	cnt[fn++] = 1;
    }
}

ll ans = 0;

ll phi(ll n) {
    ll m = (ll)sqrt(n * 1.0);
    ll ans = n;
    for (ll i = 2; i <= m; i++) {
	if (n % i == 0) {
	    ans = ans / i * (i - 1);
	    while (n % i == 0) n /= i;
	}
    }
    if (n > 1) ans = ans / n * (n - 1);
    return ans;
}

void dfs(ll u, ll sum) {
    if (u == fn) {
	ll r = n / sum;
	ans = (phi(n / sum) * phi(sum) % MOD + ans) % MOD;
	return;
    }
    for (ll i = 0; i <= cnt[u]; i++) {
	dfs(u + 1, sum);
	sum *= frc[u];
    }
}

ll solve() {
    getfrc(n);
    ans = 0;
    dfs(0, 1);
    return ans;
}

int main() {
    getprime();
    while (~scanf("%I64d%I64d", &n, &k)) {
	if (n == 1) printf("1\n");
	else if (k == 2) printf("1\n");
	else if (k > 2) printf("0\n");
	else {
	    printf("%I64d\n", solve());
	}
    }
    return 0;
}


以上是关于HDU 4983 Goffi and GCD(数论)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4982 Goffi and Squary Partition

HDU1695-GCD(数论-欧拉函数-容斥)

hdu-5656 CA Loves GCD(dp+数论)

HDU - 5584 LCM Walk (数论 GCD)

数论专题hdu2582

HDU 1722 Cake (数论 gcd)(Java版)