题解 P6583 【回首过去】
算法:整除分块
Part 1 - Subtask1 (40分)
分析一下
若
考虑
于是可以
复杂度貌似是
Part 2 - Subtask2 (80分)
考虑对于
对于每个
复杂度貌似是
Part 3 - Subtask3 (100分)
前置知识 : 整除分块(已补充于文章结尾,已经掌握的可以忽略,并确保掌握后再阅读 Part 3 的内容)
考虑更快的计算
令
但注意这里
-
t \times 2^α \times 5^β = i \le n$ 得到 $t \le \lfloor \frac{n}{2^α \times 5^β} \rfloor -
t$ 不含质因子 $2$ 和 $5
则题目变成枚举
至于怎么枚举
至于怎么剔除含质因子
复杂度算不太懂,貌似是
补充 : 其实可以发现枚举
Part 3 code :
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2000000 + 5;
typedef long long LL;
LL power(LL a, LL b) {
LL ans = 1;
for (; b; b >>= 1, a *= a)
if (b & 1) ans *= a;
return ans;
}
LL n, ans, pos[MAXN], sum[MAXN];
LL calc(LL l, LL r) {
return (r - l + 1 - r / 2 + (l - 1) / 2 - r / 5 + (l - 1) / 5 + r / 10 - (l - 1) / 10);
}
int main() {
cin >> n;
int cnt = 0;
for (LL l = 1, r; l <= n; l = r + 1) {
pos[++cnt] = r = n / (n / l);
sum[cnt] = sum[cnt - 1] + calc(l, r) * (n / l);
}
int p2 = log(n) / log(2); LL t1 = power(2, p2);
for (int i = p2; i >= 0; --i, t1 /= 2) {
int p5 = log(n / t1) / log(5); LL t2 = power(5, p5);
for (int j = p5; j >= 0; --j, t2 /= 5) {
LL lim = n / t1 / t2;
int x = lower_bound(pos + 1, pos + cnt + 1, lim) - pos - 1;
ans += sum[x] + calc(pos[x] + 1, lim) * (n / lim);
}
}
cout << ans << endl;
return 0;
}
Part X : 整除分块
有些时候会遇上形如
但当
考虑用
当
| n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 10 | 5 | 3 | 2 | 2 | 1 | 1 | 1 | 1 | 1 |
可以发现有许多相等的
于是我们针对那些
左端点只要在上一个块的右端点上加
对于
Part X code :
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += (r - l + 1) * (n / l);
}