# LOJ Chen 6491. Zrq inversion (dubius inversion)

Keywords: C++

## Sol

Inversion routine? But the last step is pretty good.

Routine enumeration (d \), simplification can get

$\sum_{T = 1}^m (\frac{M}{T})^n \sum_{d \ | T} d \mu(\frac{T}{d})$

The following is obviously in the form of Dirichlet convolution, but here \ (n \leqslant 10^{11} \) obviously can't be directly linear screened

Set \ (F(n) = n, f(n) = \phi(n) \)

According to the properties of Euler function, there are (f (n) = \ sum {D \ | n} f (d) \)

Inversion

$f(n) = \sum_{d \ | n} \mu(d) F(\frac{n}{d})$

$\phi(n) = \sum_{d \ |n} d \mu(\frac{n}{d})$

So the original formula is equal to

$\sum_{T = 1}^m (\frac{M}{T})^n \phi(T)$

Then Du Jiao sifts + number theory blocks a wave

Note that the range of linear screen should be larger

#include<bits/stdc++.h>
#define ull unsigned long long
#define LL long long
using namespace std;
const int MAXN = 1e7 + 10;
LL N, M, Lim;
int vis[MAXN], prime[MAXN], tot;
ull mp[MAXN], phi[MAXN];
void get(int N) {
vis[1] = phi[1] = 1;
for(int i = 2; i <= N; i++) {
if(!vis[i]) prime[++tot] = i, phi[i] = i - 1;
for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
vis[i * prime[j]] = 1;
if(!(i % prime[j])) {phi[i * prime[j]] = phi[i] * prime[j]; break;}
else phi[i * prime[j]] = phi[i] * phi[prime[j]];
}
}
for(int i = 2; i <= N; i++) phi[i] += phi[i - 1];
}
ull mul(ull x, ull y) {
return  x * y;
}
ull fp(ull a, ull p) {
ull base = 1;
while(p) {
if(p & 1) base = mul(base, a);
a = mul(a, a); p >>= 1;
}
return base;
}
ull S(LL x) {
if(x <= Lim) return phi[x];
else if(mp[M / x]) return mp[M / x];
ull rt;
rt = (x & 1) ? (x + 1) / 2 * (x) : (x / 2) * (x + 1);
//rt = (x + 1) * x / 2;
for(LL d = 2, nxt; d <= x; d = nxt + 1) {
nxt = x / (x / d);
rt -= (nxt - d + 1) * S(x / d);
}
return mp[M / x] = rt;
}
signed main() {
cin >> N >> M;
get(Lim = ((int)1e7));
//for(int i = 1; i <= M; i++) printf("%d ", phi[i]);
ull ans = 0;
for(LL i = 1, nxt; i <= M; i = nxt + 1) {
nxt = M / (M / i);
ans += fp(M / i, N) * (S(nxt) - S(i - 1));
//  cout << i << '\n';
}
cout << ans;
return 0;
}

Posted by dougal85 on Tue, 03 Dec 2019 00:38:41 -0800