难度
3
/
10
3/10
3/10
不学整除分块自己推很难的一题
题意
定义 F ( n ) = ∑ n i = 1 [ i ∣ x ] × i F(n)=\underset{i=1}{\overset{n}{\sum}}\big[\;i\;\big|\;x\;\big]\times i F(n)=i=1∑n[i∣∣x]×i 表示为 n n n 的所有因子的和。
求 S = ∑ a ≤ n ≤ b F ( n ) S=\underset{a\le n\le b}{\sum}F(n) S=a≤n≤b∑F(n)
数据范围
1
≤
a
≤
b
≤
1
0
12
1\le a\le b\le 10^{12}
1≤a≤b≤1012
b
−
a
≤
1
0
6
b-a\le 10^6
b−a≤106
思路
【1】首先考虑暴力枚举
求 S S S 即求 ∑ 1 ≤ n ≤ b F ( n ) − ∑ 1 ≤ n ≤ a − 1 F ( n ) \;\underset{1\le n\le b}{\sum}F(n) - \underset{1\le n\le a-1}{\sum}F(n) 1≤n≤b∑F(n)−1≤n≤a−1∑F(n)
记 G ( n ) = ∑ 1 ≤ k ≤ n F ( k ) G(n)=\underset{1\le k\le n}{\sum}F(k) G(n)=1≤k≤n∑F(k)
你每个值都是 O ( N ) O(N) O(N) 枚举判断累加答案,时间复杂度 O ( b ) = 1 0 12 O(b)=10^{12} O(b)=1012 ,不可行。
【2】考虑整除分块
普通的整除分块是
g
(
n
)
=
∑
n
i
=
1
⌊
n
i
⌋
g(n)=\underset{i=1}{\overset{n}{\sum}}\lfloor\frac{n}{i}\rfloor
g(n)=i=1∑n⌊in⌋
但是易得我们所需求的分块为
G
(
n
)
=
∑
n
i
=
1
⌊
n
i
⌋
×
i
G(n)=\underset{i=1}{\overset{n}{\sum}}\lfloor\frac{n}{i}\rfloor\times i
G(n)=i=1∑n⌊in⌋×i
于是我就不会了。。
我们枚举 G ( 12 ) G(12) G(12) 易得
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
x i \frac{x}{i} ix | 12 | 6 | 4 | 3 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 |
很多连续的
i
i
i 的情况下的系数
x
i
\frac{x}{i}
ix 也是相同的。
我们需要枚举每一个不同系数的左端点
l
l
l 和右端点
r
r
r
首先,初始化
l
=
1
l=1
l=1
对于每一个
l
l
l ,我们的新的区间的系数为
⌊
x
l
⌋
\lfloor\frac{x}{l}\rfloor
⌊lx⌋
我们需要找到最大的
r
r
r 满足
⌊
x
l
⌋
=
⌊
x
r
⌋
\lfloor \frac{x}{l}\rfloor=\lfloor \frac{x}{r} \rfloor
⌊lx⌋=⌊rx⌋
那么易得此时的
r
=
⌊
x
⌊
x
l
⌋
⌋
r=\lfloor \frac{x}{\lfloor\frac{x}{l}\rfloor}\rfloor
r=⌊⌊lx⌋x⌋
那么我们需要累加多少个
x
i
\frac{x}{i}
ix 的答案呢?
显然为
∑
r
i
=
l
⌊
x
l
⌋
×
i
=
⌊
x
l
⌋
∑
r
i
=
l
i
=
⌊
x
l
⌋
×
(
l
+
r
)
(
r
−
l
+
1
)
2
\underset{i=l}{\overset{r}{\sum}}\lfloor\frac{x}{l}\rfloor\times i=\lfloor\frac{x}{l}\rfloor \underset{i=l}{\overset{r}{\sum}}\;i=\lfloor\frac{x}{l}\rfloor\times \frac{(l+r)(r-l+1)}{2}
i=l∑r⌊lx⌋×i=⌊lx⌋i=l∑ri=⌊lx⌋×2(l+r)(r−l+1)
算完这区间,明显易得 l l l 更新为此时的 r + 1 r+1 r+1
核心代码
时间复杂度 :
O
(
log
b
)
O(\log b)
O(logb)
Time(s):125MS
/*
_ __ __ _ _
| | \ \ / / | | (_)
| |__ _ _ \ V /__ _ _ __ | | ___ _
| '_ \| | | | \ // _` | '_ \| | / _ \ |
| |_) | |_| | | | (_| | | | | |___| __/ |
|_.__/ \__, | \_/\__,_|_| |_\_____/\___|_|
__/ |
|___/
*/
#define ll unsigned long long /// 不开 ull 会 WA 一个点
ll cal(ll x){
ll l=1,r=0,ans=0;
while(l<=x){
r=x/(x/l);
ans+=(x/l)*(r-l+1)*(l+r)/2;
l=r+1;
}
return ans;
}
int main()
{
ll a,b;
cin >> a >> b;
cout << cal(b) - cal(a-1) << endl;
return 0;
}