Description
Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。
比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。
当确定N和M后,显然一共有M^N张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。
Input
两个整数N和M(N <= 15 , M <= 100000000)。
Output
可以完成任务的卡片数。
Sample Input
2 4
Sample Output
12
Hint
这12张卡片分别是:
(1, 1, 4), (1, 2, 4), (1, 3, 4), (1, 4, 4), (2, 1, 4), (2, 3, 4),
(3, 1, 4), (3, 2, 4), (3, 3, 4), (3, 4, 4), (4, 1, 4), (4, 3, 4)
这个东西第一眼看真的是一脸懵逼….
先想到既然可左可右,呢么最后的结果必然是正负一
也就是存在xi使得∑ai*xi=1;
这样看就比较简单了…
虽然我对这个什么鬼的欧几里得了解的不多..
但是知道一个结论就是必然存在两个数a,b使得ac+bd=gcd(b,d);
(怎么证?啊哈哈哈哈哈哈这种东西谁会证明啊哈哈哈哈哈哈哈根本不会证啊哈哈哈哈哈哈哈哈哈…..反证法大概可以?有空试试….)
知道这个结论了以后就可以发现只要让gcd(b,d)=1即可
那么就可以用m^n减掉gcd不是1的可能就行了….
简单的想一下如何gcd不是1比较好算…
m是确定的…想要让他们互质….就不要让gcd为m的质因数的有限倍就行
然后就挨个算算..
开始容斥…
#include
#include
#include
#include
using namespace std;
long long yinshu[50000];
long long he[50000] = { 0 };
long long geshu[50000];
long long n, m;
int u = 0;
long long quickpower(long long a, long long b)
{
long long res = 1;
while (b)
{
if (b & 1) res *= a;
a = a*a;
b >>= 1;
}
return res;
}
void dfs(long long zuobiao,long long cengshu,long long ss)
{
if (cengshu > u)return;
he[cengshu] += quickpower((long long)(m / (yinshu[zuobiao] * ss)), n);
for (long long b = zuobiao + 1;b <= u;b++)dfs(b, cengshu + 1,ss*yinshu[zuobiao]);
}
int main()
{
while (cin >> n >> m)
{
memset(yinshu, 0, sizeof(yinshu));
memset(he, 0, sizeof(he));
memset(geshu, 0, sizeof(geshu));
u = 0;
long long i = m;
for (int a = 2;a * a <= i;a++)
{
if (i%a==0)
{
yinshu[++u] = a;
while (i%a==0)i /= a;
}
}
if (i > 1)yinshu[++u] = i;
//for (int a = 1;a <= u;a++)geshu[a] = quickpower((long long)(m / yinshu[a]), n);
for (int a = 1;a <= u;a++)dfs(a, 1,1);
for (int a = 1;a <= u;a++)if (a % 2)he[a] = -he[a];
long long sum = quickpower(m, n);
for (int a = 1;a <= u;a++)sum += he[a];
cout << sum << endl;
}
return 0;
}