P3768 简单的数学题

P3768 简单的数学题

题解

题意

给定n,pn,p 求:

(i=1nj=1nijgcd(i,j))modp\bigg( \sum_{i = 1}^n \sum_{j =1}^n i j \gcd(i,j) \bigg) \bmod p

其中,n1010,5.8×108p1.1×109n \le 10 ^ {10}, 5.8 \times 10 ^ 8 \le p \le 1.1 \times 10 ^ 9

解法

首先观察到nn 的数据范围,肯定是要以一个亚线性时间复杂度跑过去的,须有用到杜教筛或Min_25筛,这里用的杜教筛。

首先化简式子:

i=1nj=1nijgcd(i,j)=d=1ndi=1nj=1nij[gcd(i,j)==d]=d=1nd3i=1ndj=1ndij[gcd(i,j)==1]\begin{aligned} \sum_{i = 1}^n \sum_{j =1}^n i j \gcd(i,j) & = \sum_{d = 1}^n d \sum_{i = 1}^n \sum_{j = 1}^n ij \left[ \gcd(i,j) == d \right] \\ & = \sum_{d = 1}^n d^3 \sum_{i = 1}^{\left\lfloor \frac{n}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor \frac{n}{d} \right\rfloor} i j \left[ \gcd(i,j) == 1 \right] \\ \end{aligned}

后面是个经典的式子,设为S(n)S(n),接着化简:

S(n)=i=1nj=1nij[gcd(i,j)==1]=i=1nj=1nijdgcd(i,j)μ(d)=d=1nμ(d)d2i=1ndj=1nd1\begin{aligned} S(n) & = \sum_{i = 1}^{n} \sum_{j = 1}^{n} i j \left[ \gcd(i,j) == 1 \right] \\ & = \sum_{i = 1}^{n} \sum_{j = 1}^{n} i j \sum_{d \mid \gcd(i,j)} \mu(d) \\ & = \sum_{d = 1}^{n} \mu(d) d^2 \sum_{i = 1}^{\left\lfloor \frac{n}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor \frac{n}{d} \right\rfloor} 1 \end{aligned}

后面的式子可以O(1)O(1)处理,再套上一个数论分块,然后就可以得到60分了,然而这并不能解决这道题,其实可以在其中的一步换一种方式去卷mu,但是有更简单的做法,重新考虑式子,对其使用欧拉反演:

有:

φ1=Id\varphi \ast 1 = Id

即:

dnφ(d)=n\sum_{d\mid n}\varphi(d) = n

原来的式子可以化为:

i=1nj=1nijgcd(i,j)=i=1nj=1nijdi,djφ(d)=d=1nφ(d)d2i=1ndj=1ndij\begin{aligned} \sum_{i = 1}^n \sum_{j = 1}^n i j \gcd(i,j) & = \sum_{i = 1}^n \sum_{j = 1}^n i j \sum_{d\mid i, d\mid j}\varphi(d) \\ & = \sum_{d = 1}^n \varphi(d) d^2 \sum_{i = 1}^{\left\lfloor \frac{n}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor \frac{n}{d} \right\rfloor} i j \end{aligned}

显然后面的式子可以O(1)O(1)计算,

n2(n+1)24\frac{n^2 (n+1)^2}{4}

现在考虑如何计算前面的

d=1nφ(d)d2\sum_{d = 1}^n \varphi(d) d^2

既然φ1=Id\varphi \ast 1 = Id,将φ(d)d2\varphi(d)d^2设为ff,设g=Id2g = Id^2显然有

(fg)n=dnφ(d)d2(nd)2=n3\bigg(f \ast g\bigg)n = \sum_{d \mid n} \varphi(d)d^2 (\frac{n}{d})^2 = n ^3

看来问题已经解决了,S(n)S(n)为我们想要求的和,

i=1n(fg)i=i=1ng(i)S(ni)=i=1ni3\sum_{i = 1}^n\bigg( f\ast g \bigg)i = \sum_{i = 1} ^ n g(i) S(\left\lfloor \frac{n}{i} \right\rfloor) = \sum_{i = 1}^n i ^ 3

然后使用技巧,

g(1)S(n)=i=1n(fg)ii=2ng(i)S(ni)g(1)S(n) = \sum_{i = 1}^n\bigg( f\ast g \bigg)i - \sum_{i = 2}^ng(i)S(\left\lfloor \frac{n}{i}\right\rfloor)

又因为g(1)=1g(1) = 1,得到递归式,

S(n)=i=1n(fg)ii=2ng(i)S(ni)S(n) = \sum_{i = 1}^n\bigg( f\ast g \bigg)i - \sum_{i = 2}^ng(i)S(\left\lfloor \frac{n}{i}\right\rfloor)

需要用到:

i=1ni2=n(n+1)(2n+1)6i=1ni3=n2(n+1)24\sum_{i = 1}^n i ^2 = \frac{n(n+1)(2n+1)}{6} \\ \sum_{i = 1}^n i ^3 = \frac{n^2 (n+1)^2}{4}

用杜教筛,时间复杂度O(n23)O(n^{\frac{2}{3}})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;

#define int long long

const int N = 5e6 + 10;

int mod;

int inv4, inv6;

inline int qpow(int a, int b)
{
int t = 1;
while(b != 0)
{
if(b & 1)t = t * a%mod;
a = a * a%mod; b >>= 1;
}
return t%mod;
}

int cnt, prime[N], phi[N];

int S_phi[N];

bool vis[N];

inline void init(int n)
{
phi[1] = 1;
for(int i = 2; i <= n; i++)
{
if(!vis[i])
{
prime[++cnt] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= cnt && prime[j] * i <= n; j++)
{
vis[i * prime[j]] = true;
if(i % prime[j] == 0)
{
phi[i * prime[j]] = prime[j] * phi[i];
break;
}
phi[i * prime[j]] = phi[i] * phi[prime[j]];
}
}
for(int i = 1; i <= n; i++)
S_phi[i] = (S_phi[i-1] + phi[i]%mod * i%mod * i%mod)%mod;
}

inline int f(int n)
{
return n %mod* n%mod * (n + 1ll)%mod * (n + 1)%mod *inv4 %mod;
}

inline int g(int n)
{
return n%mod * (n + 1)%mod * (n * 2ll%mod + 1ll)%mod *inv6 %mod;
}

unordered_map<int, int> Phi;

int S(int n)
{
if(n <= 5e6)return S_phi[n]%mod;
if(Phi.count(n))return Phi[n];
int sum = f(n)%mod;
for(int l = 2, r; l <= n; l = r + 1)
{
r = n/(n/l);
sum = (sum - S(n/l)%mod * (g(r) - g(l-1)) %mod + mod)%mod;
}
return Phi[n] = sum;
}

signed main()
{
int n;
scanf("%lld%lld", &mod, &n);
inv4 = qpow(4, mod-2);
inv6 = qpow(6, mod-2);
init(5e6);
int ans = 0;
for(int l = 1, r; l <= n; l = r + 1)
{
r = n/(n/l);
ans = (ans + f(n/l)%mod * (S(r) - S(l-1) + mod)%mod)%mod;
}
printf("%lld", ans);
return 0;
}

tips: 欧拉反演的证明

dnφ(d)=n\sum_{d \mid n} \varphi(d) = n

f(n)=dnφ(d)f(n) = \sum_{d \mid n} \varphi(d)mnm \perp n,根据欧拉函数的积性函数的性质有:

f(n)×f(m)=inφ(i)jmφ(j)=injmφ(i)φ(j)=injmφ(ij)=dnmφ(d)=f(nm)\begin{aligned} f(n) \times f(m) & = \sum_{i \mid n} \varphi(i) \sum_{j \mid m} \varphi(j) \\ & = \sum_{i \mid n} \sum_{j \mid m} \varphi(i) \varphi(j) \\ & = \sum_{i \mid n} \sum_{j \mid m} \varphi(ij) \\ & = \sum_{d \mid nm} \varphi(d) \\ & = f(nm) \end{aligned}

nn质因数分解p1c1×p2c2×p3c3××pkckp_1 ^ {c_{1}} \times p_2 ^ {c_{2}} \times p_3 ^ {c_{3}} \times \cdots \times p_k ^ {c_{k}}

所以有,

f(n)=f(p1c1)×f(p2c2)××f(pkck)f(n) = f(p_1 ^ {c_{1}}) \times f(p_2 ^ {c_{2}}) \times \cdots \times f(p_k ^ {c_{k}})

其中的每一项有:

f(pc)=i=0cφ(pi)=pcf(p ^ c) = \sum_{i = 0}^ c \varphi(p^i) = p^c

所以得证:

f(n)=f(p1c1)×f(p2c2)××f(pkck)=Πi=1kpici=n=dnφ(d)f(n) = f(p_1 ^ {c_{1}}) \times f(p_2 ^ {c_{2}}) \times \cdots \times f(p_k ^ {c_{k}}) = \Pi_{i =1}^k p_i^{c_i} = n = \sum_{d \mid n} \varphi(d)

作者

Jekyll_Y

发布于

2022-08-28

更新于

2023-03-02

许可协议

评论