洛谷 P3935 Calculating 题解 & 因数个数定理

题目传送门

题目大意: x x x 可以分解成 p 1 k 1 p 2 k 2 p 3 k 3 . . . p s k s p_1^{k_1}p_2^{k_2}p_3^{k_3}...p_s^{k_s} p1k1p2k2p3k3...psks,那么 f ( x ) = ( k 1 + 1 ) ( k 2 + 1 ) . . . ( k s + 1 ) f(x)=(k_1+1)(k_2+1)...(k_s+1) f(x)=(k1+1)(k2+1)...(ks+1),求出 ∑ i = l r f ( i ) \sum_{i=l}^r f(i) i=lrf(i)

前置知识——因数个数定理

描述: 将一个数 x x x 质因数分解后,可以表示为 x = p 1 c 1 p 2 c 2 . . . p k c k x=p_1^{c_1}p_2^{c_2}...p_k^{c_k} x=p1c1p2c2...pkck,那么 x x x 的因数个数就是 ∏ i = 1 k ( c i + 1 ) \prod\limits_{i=1}^k(c_i+1) i=1k(ci+1)

证明: 由于 x x x 的每个因子也可以表示上面的形式,只不过 c c c 的值不同,设因子的质因数分解后为 p 1 c 1 ′ p 2 c 2 ′ . . . p k c k ′ p_1^{c_1'}p_2^{c_2'}...p_k^{c_k'} p1c1p2c2...pkck,对于 c i ′ c_i' ci,它的取值范围是 0 0 0 ~ c i c_i ci,即有 ( c i + 1 ) (c_i+1) (ci+1) 种取值方案,所以总因子个数就是 ∏ i = 1 k ( c i + 1 ) \prod\limits_{i=1}^k(c_i+1) i=1k(ci+1)

题解

发现题目定义的 f ( i ) f(i) f(i) 其实就是 i i i 的因数个数。

那么考虑换一个角度,统计每一个因数 x x x 会被多少个 i i i 计算到。

显然, x x x 的每个倍数都会将 x x x 计算一次,将询问差分一下,变成 ∑ i = 1 r f ( i ) − ∑ i = 1 l − 1 f ( i ) \sum_{i=1}^rf(i)-\sum_{i=1}^{l-1}f(i) i=1rf(i)i=1l1f(i),那么问题就变成了求 1 1 1 ~ n n n 范围内有多少个 x x x 的倍数,即

∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^n \lfloor \frac n i \rfloor i=1nin

然而这是个除法分块的模板。

代码如下:

#include <cstdio>
#include <cstring>
#define mod 998244353ll
#define ll long long

ll a,b;
ll solve(ll x)
{
	ll l=1,r,re=0;
	while(l<=x)
	{
		r=x/(x/l);
		re=(re+(r-l+1)*(x/l)%mod)%mod;
		l=r+1;
	}
	return re;
}

int main()
{
	scanf("%lld %lld",&a,&b);
	printf("%lld",(solve(b)-solve(a-1)+mod)%mod);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值