BZOJ4407: 于神之怒加强版

1 2
3 3

20

HINT

1<=N,M,K<=5000000,1<=T<=2000

Solution

\begin{aligned} &\sum_{i=1}^{n}\sum_{j=1}^m(i,j)^k\\ &=\sum_{d=1}^nd^k\sum_{i=1}^{n}\sum_{j=1}^m[(i,j)=1]\\ &=\sum_{d=1}^nd^k\sum_{i=1}^{n}\sum_{j=1}^m\sum_{x|(i,j)}\mu(x)\\ &=\sum_{d=1}^nd^k\sum_{x=1}^n\mu(x)\lfloor\frac{n}{dx}\rfloor\lfloor\frac{m}{dx}\rfloor \end{aligned}

\begin{aligned} &设T=dx\\ &=\sum_{d=1}^nd^k\sum_{x=1}^n\mu(x)\lfloor\frac{n}{dx}\rfloor\lfloor\frac{m}{dx}\rfloor\\ &=\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{d|T}\mu(\frac{T}{d})d^k \end{aligned}

\begin{aligned} &设g(T)=\sum_{x|T}\mu(x)*(\frac{T}{x})^k\\ &g(i)=T^k*\sum_{x|T}\frac{\mu(x)}{x^k} \end{aligned}

\begin{aligned} g(p) &=p^k*\sum_{x|p}\frac{\mu(x)}{x^k}\\ &=p^k*\left(\frac{\mu(1)}{1^k}+\frac{\mu(p)}{p^k}\right)\\ &=p^k*(1-\frac{1}{p^k})\\ &=p^k*\frac{p^k-1}{p^k}\\ &=p^k-1 \end{aligned}

$g(i*j)=g(i)*g(j)$

\begin{aligned} &设i=r*j^c(k内不含质因子j)\\ &g(i*j)\\ &=g(r*j^{c+1})\\ &=g(r)*g(j^{c+1})\\ &考虑g(j^{c+1})=\sum_{x|j^{c+1}}\frac{\mu(x)}{x^k}\\ &显然只有当x=1或j时\mu(x)才为1，其他情况为0所以当j的指数大于2时，g值是相同的\\ &所以g(j^{c+1})=g(j^c)\\ &又因为r和j^{c+1}和j^c互质，所以有\\ &g(i*j)=g(r*j^{c+1})=g(r)*g(j^{c+1})=g(r)*g(j^c)=g(r*j^c)=g(i) \end{aligned}

$g(i*prime[j])= \begin{cases} g(i)*g(prime[j])(i与prime[j]互质)\\ g(i)(prime[j]为i的质因子) \end{cases}$

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
#define N 5000050

ll n, m;
ll p[N], cnt, mu[N];
bool vis[N];
ll F[N], k, id[N], sum[N];

ll power(ll a, ll b) { ll ans = 1;
while(b) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans % mod;
}

void init() {
cnt = 0;
mu[1] = id[1] = F[1] = 1;
for(ll i = 2; i < N; ++i) {
if(!vis[i])
id[i] = power(i, k) % mod, mu[i] = -1, p[++cnt] = i, F[i] = ((id[i] - 1) * power(id[i], mod - 2) + mod) % mod;
for(ll j = 1; j <= cnt && 1ll * p[j] * i < N; ++j) {
vis[i * p[j]] = 1;
id[i * p[j]] = id[i] * id[p[j]] % mod;
if(i % p[j] == 0) { F[i * p[j]] = F[i] % mod; break; }
mu[i * p[j]] = -mu[i];
F[i * p[j]] = F[i] * F[p[j]] % mod;
}
}
for(ll i = 1; i < N; ++i) sum[i] = (sum[i - 1] + F[i] * id[i] % mod) % mod;
}

ll calc(ll n, ll m) {
ll ans = 0;
if(n > m) swap(n, m);
for(ll l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans += 1ll * (n / l) % mod * (m / l) % mod * (sum[r] - sum[l - 1] + mod) % mod;
}
return ans % mod;
}

int main() {
int T; scanf("%d%lld", &T, &k);
init();
while(T--) {
scanf("%lld%lld", &n, &m);
printf("%lld\n", (calc(n, m) + mod) % mod);
}
}

posted @ 2019-01-30 16:16  henry_y  阅读(192)  评论(0编辑  收藏  举报