题目大意

给定 \(x,y\) ,求有多少个数列满足其 \(gcd\)\(x\) ,和为 \(y\)

题解

\(k=x/y\),若 \(k\) 不是整数则无解。否则就是求和为 \(k\)\(gcd=1\) 的序列个数

容斥考虑:

首先和为 \(k\) 的所有序列一共有\(2^{k-1}\) 个。

\(gcd!=1\) 则应减去,我们枚举 \(gcd\) 并将序列每个数除去 \(gcd\) 后,又回到了原问题。

递归解决即可。

#include<iostream>
#include<map>
#define LL long long
using namespace std;
LL x, y;
const int mod = 1e9 + 7;
map<int, int>mp;
LL ksm(LL a, LL b, LL mod)
{
	LL res = 1;
	for (; b; b >>= 1, a = a * a % mod)
		if (b & 1)res = res * a % mod;
	return res;
}
LL dfs(int x)
{
	if (mp.count(x))return mp[x];
	if (x == 1)return mp[x] = 1;
	LL res = ksm(2, x - 1, mod);
	for (int i = 1; i * i <= x; ++i)
		if (x % i == 0)
		{
			if (i == 1 || i * i == x)(res -= dfs(i)) %= mod;
			else (res -= dfs(i) + dfs(x / i)) %= mod;
		}
	return mp[x] = (res % mod + mod) % mod;
}
int main()
{
	cin >> x >> y;
	if (y % x)return puts("0") == 2333;
	cout << dfs(y / x);
	return 0;
}