洛谷 2424 约数和

题目

f ( x ) 表示为x的约数和,求 f ( x ) + + f ( y )


分析

首先要思考如何表示答案.

f ( x ) 表示为 d | x d

那么答案为

i = x y d | x d

但是时间复杂度是

O ( i = x y i )

不TLE才怪。
幸好我们换一种思想,枚举约数,
若d是1至n中的x的约数, d 2 d 3 d k d k d = x
1 <= k <= t r u n c ( x / d ) ,那么

f ( x ) = i = 1 x t r u n c ( x / i ) i

于是就想到了前缀和

i = x y f ( i ) = i = 1 y t r u n c ( y / i ) i

i = 1 x 1 t r u n c ( ( x 1 ) / i ) i

但是时间复杂度为 O ( y ) 还会TLE
如何优化 i = 1 x t r u n c ( x / i ) i

f(12)
i 1 2 3 4 5 6 7 8 9 10 11 12
12/i 12 6 4 3 2 2 1 1 1 1 1 1

对于重复的数字
就用区间(l to r)优化
l很简单, l = r + 1 ,那么 r = n / ( n / l )
l是下标,n/l自然就是约数
ans+=约数的个数*约数
约数为n/l
约数的个数就是 i = l r i
改等差数列为 ( l + r ) ( r l + 1 ) / 2
然后就能轻松AC了。


代码

#include<cstdio>
using namespace std;
long long sum(int n){
    long long ans=0;
    for(long long l=1,r;l<=n;l=r+1) {
        r=n/(n/l);
        ans+=(n/l)*(l+r)*(r-l+1)/2;
    }
    return ans;
}
int main() {
    int x,y;
    scanf("%d%d",&x,&y);
    printf("%lld\n",sum(y)-sum(x-1));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/80752207