2020ICPC 江西省大学生程序设计竞赛A-A Simple Math Problem 莫比乌斯反演
传送门: https://ac.nowcoder.com/acm/contest/8827/A
题意
求
解
∑
i
=
1
n
∑
j
=
1
i
[
g
c
d
(
i
,
j
)
=
1
]
F
[
j
]
求解\sum_{i=1}^n\sum_{j=1}^i[gcd(i,j)=1]F[j]
求解i=1∑nj=1∑i[gcd(i,j)=1]F[j]
F
[
j
]
为
j
各
个
数
位
之
和
,
例
如
F
[
123
]
=
1
+
2
+
3
=
6
。
F[j]为j各个数位之和,例如F[123]=1+2+3=6。
F[j]为j各个数位之和,例如F[123]=1+2+3=6。
思路
前
置
技
能
:
φ
∗
i
d
=
μ
μ
∗
I
=
ε
前置技能:\red{\varphi * id=\mu\;\;\;\;\mu*I=\varepsilon }
前置技能:φ∗id=μμ∗I=ε
先
来
看
∑
i
=
1
n
∑
j
=
1
i
F
[
j
]
,
可
以
直
接
等
价
于
∑
i
=
1
n
∑
j
=
i
n
F
[
i
]
,
可
手
动
验
证
一
下
。
先来看\sum_{i=1}^n\sum_{j=1}^iF[j],可以直接等价于\sum_{i=1}^n\sum_{j=i}^nF[i],可手动验证一下。
先来看∑i=1n∑j=1iF[j],可以直接等价于∑i=1n∑j=inF[i],可手动验证一下。
∑ i = 1 n ∑ j = 1 i [ g c d ( i , j ) = 1 ] F [ j ] \sum_{i=1}^n\sum_{j=1}^i[gcd(i,j)=1]F[j] i=1∑nj=1∑i[gcd(i,j)=1]F[j]
∑ i = 1 n ∑ j = i n F [ i ] ∑ d ∣ i d ∣ j μ ( d ) \sum_{i=1}^n\sum_{j=i}^nF[i]\sum_{d|i\;d|j}\mu(d) i=1∑nj=i∑nF[i]d∣id∣j∑μ(d)
枚
举
d
:
枚举d:
枚举d:
∑
i
=
1
n
F
[
i
]
∑
d
∣
i
μ
(
d
)
∑
⌊
i
d
⌋
⌊
n
d
⌋
1
\sum_{i=1}^nF[i]\sum_{d|i}\mu(d)\sum_{\left \lfloor \frac{i}{d} \right \rfloor }^{\left \lfloor \frac{n}{d} \right \rfloor }1
i=1∑nF[i]d∣i∑μ(d)⌊di⌋∑⌊dn⌋1
∑ i = 1 n F [ i ] ( ∑ d ∣ i μ ( d ) ∗ ( n − i d ) ) \sum_{i=1}^nF[i]\left ( \sum_{d|i}\mu(d)*(\frac{n-i}{d}) \right ) i=1∑nF[i]⎝⎛d∣i∑μ(d)∗(dn−i)⎠⎞
∑ i = 1 n F [ i ] ( ∑ d ∣ i μ ( d ) n d − ∑ d ∣ i μ ( d ) i d ) \sum_{i=1}^nF[i]\left ( \sum_{d|i}\mu(d)\frac{n}{d}-\sum_{d|i}\mu(d)\frac{i}{d}\right ) i=1∑nF[i]⎝⎛d∣i∑μ(d)dn−d∣i∑μ(d)di⎠⎞
设 f ( i ) = ∑ d ∣ i μ ( d ) n d , ∑ d ∣ i μ ( d ) i d = φ , 得 : 设\blue{f(i)=\sum_{d|i}\mu(d)\frac{n}{d},\sum_{d|i}\mu(d)\frac{i}{d}=\varphi},得: 设f(i)=∑d∣iμ(d)dn,∑d∣iμ(d)di=φ,得:
∑ i = 1 n F [ i ] ∗ ( f ( i ) − φ ( i ) ) \sum_{i=1}^nF[i]*(f(i)-\varphi(i)) i=1∑nF[i]∗(f(i)−φ(i))
μ 、 φ 、 F 和 f 预 处 理 , 然 后 O ( n ) 得 答 案 。 \red{\mu、\varphi、F和f预处理,然后O(n)得答案。} μ、φ、F和f预处理,然后O(n)得答案。
Code(20MS)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)
// const ll mod = 998244353;
const ll mod = 1e9 + 7;
// const double eps = 1e-6;
// const double PI = acos(-1);
// const double R = 0.57721566490153286060651209;
const int N = 1e6 + 10;
int mu[N], f[N], phi[N];
int F[N];
bool is_prime[N];
int prime[N];
int cnt;
int n;
int Clac(int x) {
int res = 0;
while(x) {
res += x % 10;
x /= 10;
}
return res;
}
void Init() {
mu[1] = 1;is_prime[0] = is_prime[1] = true;
for(int i = 2;i < N; i++) {
if (!is_prime[i]) {
mu[i] = -1;
phi[i] = i - 1;
prime[++cnt] = i;
}
for (int j = 1; j <= cnt && i * prime[j] < N; j++) {
is_prime[i * prime[j]] = true;
if(i % prime[j]) {
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
else {
phi[i * prime[j]] = phi[i] * prime[j];
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = -mu[i];
}
}
for(int i = 1;i <= n; i++) {
F[i] = Clac(i);
for(int j = i;j <= n; j += i) {
f[j] += mu[i] * (n / i);
}
}
}
void solve() {
cin >> n;
Init();
ll ans = 0;
for(int i = 1;i <= n; i++) {
ans += 1ll * F[i] * (f[i] - phi[i]);
}
cout << ans << endl;
}
signed main() {
ios_base::sync_with_stdio(false);
//cin.tie(nullptr);
//cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug = 0;
do {
if (acm_local_for_debug == '$') exit(0);
if (test_index_for_debug > 20)
throw runtime_error("Check the stdin!!!");
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
} while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
solve();
#endif
return 0;
}