集合统计 / 简单的数学题 / 数学
题目链接:ybt金牌导航8-4-7 / SSL 2639 / bzoj 4173
题目大意
给你 n,m 要你求 φ(n)*φ(m)*sum φ(ai)。
其中 ai 是满足 n%x+m%x>=x 的所有 x。
思路
重新写式子:
设集合
S
(
n
,
m
)
S(n,m)
S(n,m) 为满足
n
%
k
+
m
%
k
⩾
k
n\%k+m\%k\geqslant k
n%k+m%k⩾k 的
k
k
k 组成的集合。
然后要你求: φ ( n ) φ ( m ) ∑ k ∈ S ( n , m ) φ ( k ) \varphi(n)\varphi(m)\sum\limits_{k\in S(n,m)}\varphi(k) φ(n)φ(m)k∈S(n,m)∑φ(k)
其实你看样例啊什么都都可以猜出来,最右边这个是 n ∗ m n*m n∗m。
这里给一下证明:
k
⌊
n
k
⌋
+
n
%
k
=
n
k\left\lfloor\frac{n}{k}\right\rfloor+n\%k=n
k⌊kn⌋+n%k=n
k
⌊
m
k
⌋
+
m
%
k
=
m
k\left\lfloor\frac{m}{k}\right\rfloor+m\%k=m
k⌊km⌋+m%k=m
两个加起来:
k
⌊
n
k
⌋
+
n
%
k
+
k
⌊
m
k
⌋
+
m
%
k
=
n
+
m
k\left\lfloor\frac{n}{k}\right\rfloor+n\%k+k\left\lfloor\frac{m}{k}\right\rfloor+m\%k=n+m
k⌊kn⌋+n%k+k⌊km⌋+m%k=n+m
(
k
⌊
n
k
⌋
+
k
⌊
m
k
⌋
)
+
(
n
%
k
+
m
%
k
)
=
n
+
m
(k\left\lfloor\frac{n}{k}\right\rfloor+k\left\lfloor\frac{m}{k}\right\rfloor)+(n\%k+m\%k)=n+m
(k⌊kn⌋+k⌊km⌋)+(n%k+m%k)=n+m
然后根据
n
%
k
+
m
%
k
⩾
k
n\%k+m\%k\geqslant k
n%k+m%k⩾k 代替进去:
k
(
⌊
n
k
⌋
+
⌊
m
k
⌋
)
+
k
⩽
n
+
m
k(\left\lfloor\frac{n}{k}\right\rfloor+\left\lfloor\frac{m}{k}\right\rfloor)+k\leqslant n+m
k(⌊kn⌋+⌊km⌋)+k⩽n+m
然后显然
n
%
k
+
m
%
k
≤
2
k
n\%k+m\%k\leq 2k
n%k+m%k≤2k,所以它除
k
k
k 向下取整是
1
1
1。
那我们就全部除
k
k
k 向下取整,那它前面
⩾
\geqslant
⩾ 就肯定是
=
=
= 了。
⌊
n
k
⌋
+
⌊
m
k
⌋
+
1
=
⌊
n
+
m
k
⌋
\left\lfloor\frac{n}{k}\right\rfloor+\left\lfloor\frac{m}{k}\right\rfloor+1= \left\lfloor \frac{n+m} {k}\right\rfloor
⌊kn⌋+⌊km⌋+1=⌊kn+m⌋
⌊
n
+
m
k
⌋
−
⌊
n
k
⌋
−
⌊
m
k
⌋
=
1
\left\lfloor \frac{n+m}{k}\right\rfloor-\left\lfloor\frac{n}{k}\right\rfloor-\left\lfloor\frac{m}{k}\right\rfloor=1
⌊kn+m⌋−⌊kn⌋−⌊km⌋=1
然后我们带进去:
∑
k
∈
S
(
n
,
m
)
φ
(
k
)
\sum\limits_{k\in S(n,m)}\varphi(k)
k∈S(n,m)∑φ(k)
∑
k
=
1
n
+
m
φ
(
k
)
∗
⌊
n
+
m
k
⌋
−
∑
k
=
1
n
φ
(
k
)
⌊
n
k
⌋
−
∑
k
=
1
m
φ
(
k
)
⌊
m
k
⌋
\sum\limits_{k=1}^{n+m}\varphi(k)*\left\lfloor \frac{n+m}{k}\right\rfloor-\sum\limits_{k=1}^{n}\varphi(k)\left\lfloor\frac{n}{k}\right\rfloor-\sum\limits_{k=1}^{m}\varphi(k)\left\lfloor\frac{m}{k}\right\rfloor
k=1∑n+mφ(k)∗⌊kn+m⌋−k=1∑nφ(k)⌊kn⌋−k=1∑mφ(k)⌊km⌋
这里我看了半天才知道为什么,就是因为你上面这个式子:
⌊
n
+
m
k
⌋
−
⌊
n
k
⌋
−
⌊
m
k
⌋
\left\lfloor \frac{n+m}{k}\right\rfloor-\left\lfloor\frac{n}{k}\right\rfloor-\left\lfloor\frac{m}{k}\right\rfloor
⌊kn+m⌋−⌊kn⌋−⌊km⌋
它肯定是
0
/
1
0/1
0/1,那不符合的情况就是
0
0
0,那就无影响也可以加上,然后右边两个因为大了之后除向下取整的结果肯定是
0
0
0 所以可以都不要。
然后你考虑
∑
i
=
1
x
φ
(
i
)
⌊
x
i
⌋
\sum\limits_{i=1}^x\varphi(i)\left\lfloor\frac{x}{i}\right\rfloor
i=1∑xφ(i)⌊ix⌋ 怎么求。
∑
i
=
1
n
φ
(
i
)
⌊
n
i
⌋
=
∑
j
=
1
n
∑
i
∣
j
φ
(
i
)
=
∑
j
=
1
n
j
\sum\limits_{i=1}^n\varphi(i)\left\lfloor\frac{n}{i}\right\rfloor=\sum\limits_{j=1}^n\sum\limits_{i|j}\varphi(i)=\sum\limits_{j=1}^nj
i=1∑nφ(i)⌊in⌋=j=1∑ni∣j∑φ(i)=j=1∑nj
然后就成了:
∑
k
=
1
n
+
m
k
−
∑
k
=
1
n
k
−
∑
k
=
1
m
k
\sum\limits_{k=1}^{n+m}k-\sum\limits_{k=1}^{n}k-\sum\limits_{k=1}^{m}k
k=1∑n+mk−k=1∑nk−k=1∑mk
然后三个等差序列和你化简一下就成了 n ∗ m n*m n∗m。
代码
#include<cstdio>
#define ll long long
#define mo 998244353
using namespace std;
ll n, m, pr[4000001];
ll ans;
bool np[40000001];
ll phi(ll now) {
ll re = 1;
for (int i = 1; i <= pr[0] && pr[i] * pr[i] <= now; i++) {
if (now % pr[i] == 0) {
re = re * (pr[i] - 1) % mo;
now /= pr[i];
while (now % pr[i] == 0) {
re = re * pr[i] % mo; now /= pr[i];
}
}
}
if (now > 1) {
re = re * (now - 1) % mo;
}
return re;
}
int main() {
for (int i = 2; i <= 4e7; i++) {
if (!np[i]) pr[++pr[0]] = i;
for (int j = 1; j <= pr[0] && i * pr[j] <= 4e7; j++) {
np[i * pr[j]] = 1; if (i % pr[j] == 0) break;
}
}
scanf("%lld %lld", &n, &m);
ans = (n % mo) * (m % mo) % mo;//直接上结论
printf("%lld", ans * phi(n) % mo * phi(m) % mo);
return 0;
}