#整除分块#洛谷 3935 Calculating

本文介绍了一种计算区间[l, r]内所有整数的约数个数之和的有效算法。通过将问题转化为计算前缀和的形式,并利用整除分块技巧,实现了高效的求解过程。

题目

[l∼r][l\sim r][lr]的约数个数和


分析

首先可以把它用前缀和表示,那关键是怎么实现呢?
f[n]f[n]f[n][1∼n][1\sim n][1n]的约数个数和,那么f[n]=∑i=1n⌊ni⌋(转换成枚举约数的思想)f[n]=\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor(转换成枚举约数的思想)f[n]=i=1nin()
那么就可以用整除分块求解


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <queue>
#define min(a,b) ((a)<(b)?(a):(b))
#define rr register
using namespace std;
typedef long long ll;
const ll mod=998244353;
inline ll iut(){
    rr ll ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
inline signed mo(int x){return x>=mod?x-mod:x;}
inline signed answ(ll n){
    rr int ans=0;
    for (rr ll l=1,r;l<=n;l=r+1)
        r=n/(n/l),ans=mo(ans+(n/l)*(r-l+1)%mod);
    return ans;
}
signed main(){
    rr ll l=iut(),r=iut();
    return !printf("%d",mo(answ(r)-answ(l-1)+mod));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值