题意:给定
n
,
m
,
d
n,m,d
n,m,d,求
∑
i
=
1
n
∑
j
=
1
m
(
g
c
d
(
i
,
j
)
B
)
\sum_{i=1}^n\sum_{j=1}^m\binom{gcd(i,j)}{B}
i=1∑nj=1∑m(Bgcd(i,j))
直接反演
∑
d
=
1
n
(
d
B
)
∑
l
=
1
n
d
μ
(
l
)
⌊
n
d
l
⌋
⌊
m
d
l
⌋
\sum_{d=1}^n\binom{d}{B}\sum_{l=1}^{\frac{n}{d}}\mu (l)\left \lfloor \frac{n}{dl} \right \rfloor\left \lfloor \frac{m}{dl} \right \rfloor
d=1∑n(Bd)l=1∑dnμ(l)⌊dln⌋⌊dlm⌋
化到这步的时候我想的是
对前面整除分块,组合数列求和,内层套一个整除分块,内层套的时候用杜教筛
μ
\mu
μ 的前缀和
算了一下复杂度,发现是
∑
i
=
1
n
n
i
=
n
3
/
4
\sum_{i=1}^{\sqrt n}\sqrt \frac{n}{i}=n^{3/4}
∑i=1nin=n3/4,加上杜教筛的
O
(
n
2
/
3
)
O(n^{2/3})
O(n2/3),亲测大样例
10
s
10s
10s
我们按照套路对上式继续化简,枚举
d
l
dl
dl
∑
T
=
1
n
⌊
n
T
⌋
⌊
m
T
⌋
∑
l
∣
T
μ
(
l
)
(
T
/
l
B
)
\sum_{T=1}^n\left \lfloor \frac{n}{T} \right \rfloor\left \lfloor \frac{m}{T} \right \rfloor\sum_{l|T}\mu (l)\binom{T/l}{B}
T=1∑n⌊Tn⌋⌊Tm⌋l∣T∑μ(l)(BT/l)
考虑直接筛后面一坨的前缀和就可以整除分块
令
f
(
T
)
=
∑
l
∣
T
μ
(
l
)
(
T
/
l
B
)
f(T)=\sum_{l|T}\mu (l)\binom{T/l}{B}
f(T)=∑l∣Tμ(l)(BT/l)
S
(
n
)
=
∑
i
=
1
n
f
(
n
)
S(n)=\sum_{i=1}^nf(n)
S(n)=∑i=1nf(n)
考虑到有
μ
\mu
μ,卷上一个
I
I
I
那么就有
I
∗
S
(
n
)
=
∑
i
=
1
n
∑
l
∣
i
(
i
/
l
B
)
[
l
=
1
]
=
∑
i
=
1
n
(
i
B
)
=
(
n
+
1
B
+
1
)
I*S(n)=\sum_{i=1}^n\sum_{l|i}\binom{i/l}{B}[l=1]=\sum_{i=1}^n\binom{i}{B}=\binom{n+1}{B+1}
I∗S(n)=i=1∑nl∣i∑(Bi/l)[l=1]=i=1∑n(Bi)=(B+1n+1)
所以
I
∗
S
(
n
)
=
S
(
n
)
+
∑
i
=
2
n
S
(
⌊
n
i
⌋
)
=
(
n
+
1
B
+
1
)
I*S(n)=S(n)+\sum_{i=2}^nS(\left \lfloor \frac{n}{i} \right \rfloor)=\binom{n+1}{B+1}
I∗S(n)=S(n)+i=2∑nS(⌊in⌋)=(B+1n+1)
杜教筛即可,预处理往大的预处理,由于带
l
o
g
log
log,到
3
e
6
3e6
3e6 就已经差不多了
复杂度是整除分块的
O
(
n
)
O(\sqrt n)
O(n) 和杜教筛的
O
(
n
2
/
3
)
O(n^{2/3})
O(n2/3)
然后组合数还要用一下
l
u
c
a
s
lucas
lucas
#include<bits/stdc++.h>
#define cs const
#include<tr1/unordered_map>
using namespace std;
using namespace tr1;
typedef long long ll;
ll read(){
ll cnt = 0, f = 1; char ch = 0;
while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }
while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
return cnt * f;
}
cs int Mod = 9990017;
ll n, m, B;
int fac[Mod + 5], ifac[Mod + 5];
ll add(ll a, ll b){ return (a + b) >= Mod ? (a + b) % Mod : a + b; }
ll mul(ll a, ll b){ if(a >= Mod) a %= Mod; if(b >= Mod) b %= Mod; ll r = a * b; if(r >= Mod) r %= Mod; return r; }
ll ksm(ll a, ll b){ ll ans = 1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans = mul(ans, a); return ans; }
ll C(ll n, ll m){
if(n < 0 || m < 0 || n < m) return 0;
return mul(fac[n], mul(ifac[m], ifac[n-m]));
}
ll Lucas(ll n, ll m){
if(n < Mod && m < Mod) return C(n, m);
return mul(Lucas(n / Mod, m / Mod), C(n % Mod, m % Mod));
}
cs int K = 5e6;
int prim[K + 5]; bool isp[K + 5];
int tot, mu[K + 5], f[K + 5], g[K + 5];
ll calc(ll x){ return Lucas(x + 1, B + 1); }
unordered_map<ll, int> MP;
ll F(ll x){
if(x <= K) return f[x];
if(MP.count(x)) return MP[x];
ll ans = Lucas(x + 1, B + 1);
for(ll l = 2, r; l <= x; l = r + 1){
ll v = x / l; r = x / v;
ans = add(ans, Mod - mul(r-l+1, F(v)));
} return MP[x] = ans;
}
void prework(){
fac[0] = fac[1] = ifac[0] = ifac[1] = 1;
for(int i = 2; i < Mod; i++) fac[i] = mul(fac[i-1], i);
ifac[Mod-1] = ksm(fac[Mod-1], Mod-2);
for(int i = Mod-2; i >= 2; i--) ifac[i] = mul(ifac[i+1], i+1);
mu[1] = 1;
for(int i = 2; i <= K; i++){
if(!isp[i]) prim[++tot] = i, mu[i] = -1;
for(int j = 1; j <= tot; j++){
if(i * prim[j] > K) break;
isp[i * prim[j]] = 1;
if(i % prim[j] == 0) break;
mu[i * prim[j]] = mu[i] * mu[prim[j]];
}
}
for(int i = 1; i <= K; i++) g[i] = C(i, B);
for(int i = 1; i <= K; i++){
for(int j = i; j <= K; j += i){
f[j] = add(f[j], mul(mu[i], g[j / i]));
}
}
for(int i = 1; i <= K; i++) f[i] = add(f[i-1], f[i]);
}
int main(){
n = read(), m = read(), B = read();
if(n > m) swap(n, m);
prework();
ll ans = 0, las = 0;
for(ll l = 1, r; l <= n; l = r + 1){
ll v1 = n / l, v2 = m / l; r = min(n / v1, m / v2);
ll nx = F(r);
ans = add(ans, mul(add(nx, Mod - las), mul(v1, v2)));
las = nx;
} cout << ans; return 0;
}