CF900D Unusual Sequences

显然我们需要 \(x|y\),不妨令 \(n={y\over x}\),则变成求 \(\gcd(a_1,a_2,...,a_n)=1\)\(\sum a_i=n\) 的个数。

\(f(n)\) 为答案,考虑反演。设 \(g(n)\) 为满足后面一个条件的序列个数,由插板法知: \(g(n)=2^{n-1}\),我们可以得到式子:

\[g(n)=\sum_{d|n} f(n) \]

我们可以莫比乌斯反演一下:

\[f(n)=\sum_{d|n}\mu(d)g({n\over d}) \]

\(n\) 的因数数量很少,可以通过。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 100005, mod = 1e9 + 7;

inline int power(int a, int b) {
	int t = 1, y = a, k = b;
	while (k) {
		if (k & 1) t = (1ll * t * y) % mod;
		y = (1ll * y * y) % mod; k >>= 1;
	} return t;
}

inline int mu(int x) {
	int t = x, ret = 1;
	for (int i = 2; i * i <= t; ++i) {
		if (t % i) continue;
		if (!((t / i) % i)) return 0;
		t /= i; ret = -ret;
	} if (t != 1) ret = -ret; return ret;
}

int x, y;

int main() {
	scanf("%d%d", &x, &y);
	if (y % x) return puts("0") & 0;
	int ans = 0, n = y / x;
	for (int i = 1; i * i <= n; ++i) {
		if (n % i) continue;
		ans += mu(i) * power(2, n / i - 1);
		if (ans >= mod) ans -= mod; if (ans < 0) ans += mod;
		if (i * i != n) {
			ans += mu(n / i) * power(2, i - 1);
			if (ans >= mod) ans -= mod; if (ans < 0) ans += mod;
		}
	} printf("%d", ans);
	return 0;
}
posted @ 2021-09-15 17:27  Smallbasic  阅读(25)  评论(0)    收藏  举报