2018ACM-ICPC徐州網路賽 D Easy Math
阿新 • • 發佈:2019-02-06
記:
直接遞迴做吧
當時,返回,這個可以參考我的另一篇https://blog.csdn.net/meopass/article/details/82628563。
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#include <ext/rope>
#include <ext/pb_ds/priority_queue.hpp>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#define eps 1e-8
const double pi = acos (-1.0);
typedef long long LL;
typedef long long DLL;
typedef unsigned long long ULL;
void umax(LL &a, LL b) {
a = max(a, b);
}
void umin(LL &a, LL b) {
a = min(a, b);
}
int dcmp(double x) {
return fabs(x) <= eps?0:(x > 0?1:-1);
}
void file() {
freopen("data_in.txt", "r", stdin);
freopen("data_out.txt", "w", stdout);
}
DLL mod = 1e9+7;
DLL Pow(DLL a,DLL b) {
DLL res=1;
a%=mod;
for(; b; b>>=1) {
if(b&1)res=res*a%mod;
a=a*a%mod;
}
return res;
}
//
//void print(DLL x) {
// if(x < 0) {
// x = -x;
// putchar('-');
// }
// if(x > 9) print(x/10);
// putchar(x%10 + '0');
//}
//#define iostart
#define pb(x) push_back(x)
namespace solver {
const LL maxn = 1e7;
map<pair<LL, LL>, LL> mp;
bool tag[maxn];
LL p[maxn/10], mob[maxn], premob[maxn];
LL cnt;
void shai() {
mob[1] = 1;
cnt = 0;
for (LL i = 2; i < maxn; i++) {
if (!tag[i]) {
p[cnt++] = i;
mob[i] = -1;
}
for (LL j = 0; j < cnt && i * p[j] < maxn; j++) {
tag[i*p[j]] = 1;
if (i % p[j] == 0){
mob[i*p[j]]=0;
break;
}
mob[i*p[j]] = -mob[i];
}
}
for (LL i = 1; i < maxn; i++) {
premob[i] = premob[i-1] + mob[i];
}
}
LL getmu(LL n) {
if (n < maxn) return mob[n];
LL ans = 1;
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
int cnt = 0;
while (n % i == 0) {
n /= i;
cnt ++;
if (cnt >= 2) return 0;
}
ans *= -1;
}
}
if (n != 1) {
ans *= -1;
}
return ans;
}
unordered_map<LL, LL> mppremu;
LL getpremu(LL n) {
if (n < maxn) {
return premob[n];
}
if (mppremu.count(n)) {
return mppremu[n];
}
LL ans = 1;
for (LL i = 2, last; i <= n; i=last+1) {
last = n / (n / i);
ans -= (last - i + 1) * getpremu(n/i);
}
return mppremu[n] = ans;
}
LL get(LL m, LL n) {
if (m == 0) {
return 0;
}
if (n == 1) {
return getpremu(m);
}
LL v = getmu(n);
if (m == 1) {
return v;
}
if (v == 0) {
return 0;
}
if (mp.count({m, n})) return mp[{m, n}];
LL ans = 0;
for (LL i = 1; i <= sqrt(n); i++) {
if (n % i == 0) {
ans += get(m/i, i)*getmu(i);
if (i * i != n) {
ans += get(m/(n/i), n/i)*getmu(n/i);
}
}
}
return mp[{m,n}] = v * ans;
}
void solve() {
shai();
LL m, n;
scanf("%lld%lld", &m, &n);
printf("%lld\n", get(m, n));
}
}
int main() {
#ifdef iostart
ios::sync_with_stdio(0);
cin.tie(0);
#endif // iostart
// file();
solver::solve();
return 0;
}