P6825 「EZEC-4」求和
求:
∑
i
=
1
n
∑
j
=
1
n
gcd
(
i
,
j
)
i
+
j
\sum_{i=1}^{n}\sum_{j=1}^{n}\gcd(i,j)^{i+j}
i=1∑nj=1∑ngcd(i,j)i+j
先化简原式,有:
∑
i
=
1
n
∑
j
=
1
n
gcd
(
i
,
j
)
i
+
j
=
∑
d
=
1
n
∑
i
=
1
n
∑
j
=
1
n
d
i
+
j
[
gcd
(
i
,
j
)
=
d
]
=
∑
d
=
1
n
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
d
⌋
d
d
⋅
(
i
+
j
)
[
gcd
(
i
,
j
)
=
1
]
=
∑
d
=
1
n
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
d
⌋
d
d
⋅
(
i
+
j
)
∑
p
∣
gcd
(
i
,
j
)
μ
(
p
)
=
∑
d
=
1
n
∑
p
=
1
⌊
n
d
⌋
μ
(
p
)
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
d
⌋
d
d
⋅
(
i
+
j
)
[
p
∣
i
]
[
p
∣
j
]
=
∑
d
=
1
n
∑
p
=
1
⌊
n
d
⌋
μ
(
p
)
∑
i
=
1
⌊
n
p
d
⌋
∑
j
=
1
⌊
n
p
d
⌋
d
d
p
⋅
(
i
+
j
)
=
∑
d
=
1
n
∑
p
=
1
⌊
n
d
⌋
μ
(
p
)
∑
i
=
1
⌊
n
T
⌋
∑
j
=
1
⌊
n
T
⌋
d
T
⋅
(
i
+
j
)
T
=
d
p
=
∑
d
=
1
n
∑
p
=
1
⌊
n
d
⌋
μ
(
p
)
∑
i
=
1
⌊
n
T
⌋
(
d
T
)
i
∑
j
=
1
⌊
n
T
⌋
(
d
T
)
j
=
∑
d
=
1
n
∑
p
=
1
⌊
n
d
⌋
μ
(
p
)
(
∑
i
=
1
⌊
n
T
⌋
(
d
T
)
i
)
2
\begin{aligned} &\sum_{i=1}^{n}\sum_{j=1}^{n}\gcd(i,j)^{i+j}\\ &=\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}d^{i+j}[\gcd(i,j)=d]\\ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}d^{d\cdot(i+j)}[\gcd(i,j)=1]\\ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}d^{d\cdot(i+j)}\sum_{p|\gcd(i,j)}\mu(p)\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}d^{d\cdot(i+j)}[p|i][p|j]\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{pd}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{pd}\rfloor}d^{dp\cdot(i+j)}\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{T}\rfloor}d^{T\cdot(i+j)} & T=dp\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}(d^T)^i\sum_{j=1}^{\lfloor\frac{n}{T}\rfloor}(d^T)^j\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\left(\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}(d^T)^i\right)^2 \end{aligned}
i=1∑nj=1∑ngcd(i,j)i+j=d=1∑ni=1∑nj=1∑ndi+j[gcd(i,j)=d]=d=1∑ni=1∑⌊dn⌋j=1∑⌊dn⌋dd⋅(i+j)[gcd(i,j)=1]=d=1∑ni=1∑⌊dn⌋j=1∑⌊dn⌋dd⋅(i+j)p∣gcd(i,j)∑μ(p)=d=1∑np=1∑⌊dn⌋μ(p)i=1∑⌊dn⌋j=1∑⌊dn⌋dd⋅(i+j)[p∣i][p∣j]=d=1∑np=1∑⌊dn⌋μ(p)i=1∑⌊pdn⌋j=1∑⌊pdn⌋ddp⋅(i+j)=d=1∑np=1∑⌊dn⌋μ(p)i=1∑⌊Tn⌋j=1∑⌊Tn⌋dT⋅(i+j)=d=1∑np=1∑⌊dn⌋μ(p)i=1∑⌊Tn⌋(dT)ij=1∑⌊Tn⌋(dT)j=d=1∑np=1∑⌊dn⌋μ(p)⎝⎛i=1∑⌊Tn⌋(dT)i⎠⎞2T=dp
再看后面那部分,令 x = T p T x=\frac{T}{p}^T x=pTT。
设
S
n
S_n
Sn 为等比数列前
n
n
n 项和,则有:
S
n
=
S
⌊
n
2
⌋
(
1
+
a
⌊
n
2
⌋
)
+
a
n
[
2
∤
n
]
S_n=S_{\lfloor\frac{n}{2}\rfloor}(1+a^{\lfloor\frac{n}{2}\rfloor})+a^n[2 \nmid n]
Sn=S⌊2n⌋(1+a⌊2n⌋)+an[2∤n]
即可
O
(
log
n
)
\mathcal O(\log n)
O(logn) 求解。
时间复杂度 O ( n log n ) \mathcal O(n \log n) O(nlogn)。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pll pair<ll, ll>
#define mpr make_pair
#define fi first
#define se second
const int _ = 1.5e6 + 10;
int mod;
int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int qpow(int x, int y)
{
int res = 1;
while (y)
{
if (y & 1)
res = 1ll * res * x % mod;
x = 1ll * x * x % mod;
y >>= 1;
}
return res;
}
pll qsum(int a, int n)
{
if (n == 0)
return mpr(1, 1);
if (n == 1)
return mpr(a, a);
pll tmp = qsum(a, n / 2);
if (n & 1)
return mpr((tmp.fi * (tmp.se + 1) % mod + tmp.se * tmp.se % mod * a % mod) % mod, tmp.se * tmp.se % mod * a % mod);
else
return mpr(tmp.fi * (tmp.se + 1) % mod, tmp.se * tmp.se % mod);
}
int T, n, m, k;
bitset<_> vis;
int cnt, pri[_], mu[_];
void init(int n)
{
mu[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!vis[i])
pri[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * pri[j] <= n; j++)
{
vis[i * pri[j]] = 1;
if (i % pri[j] == 0)
break;
mu[i * pri[j]] = -mu[i];
}
}
}
int solve(int n)
{
int ans = 0;
for (int d = 1; d <= n; d++)
{
int a = qpow(d, d);
int b = a;
for (int p = 1; p <= n / d; p++)
{
pll tmp = qsum(b, n / (d * p));
ans = (ans + tmp.fi * tmp.fi % mod * (mu[p] + mod) % mod) % mod;
b = 1ll * b * a % mod;
}
}
return ans;
}
signed main()
{
T = read();
init(_ - 10);
while (T--)
{
n = read(), mod = read();
printf("%d\n", solve(n));
}
return 0;
}