1.其中i从1增加到n为等差数列, 的值随i的增加具有阶梯性(下降),故可将其分为一个一个台阶进行计算。即整除分块
对于一个 ,值与其相同的最后一个
有
,利用该性质对每个台阶左端点
可求出台阶右端点
。
2.对于每个台阶, 相同,i的值为等差数列,设l,r分别为台阶左、右端点。每个台阶的值 :
3.ans=n*k-所有台阶的值之和。
注意判断的情况,以及台阶右端点不能大于n。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int main()
{
//freopen("1.txt","r",stdin);
ll n,k,ans;
scanf("%lld%lld",&n,&k);
ll l,r;
ans=n*k;
for(ll i=1;i<=n;)
{
if(k/i==0)
break;
r=min(k/(k/i),n);
ans-=(i+r)*(r-i+1)/2*(k/i);
i=r+1;
// cout<<1<<endl;
}
printf("%lld\n",ans);
return 0;
}
本文深入探讨了整除分块算法的原理及其在解决特定数学问题中的应用。通过将等差数列按其值的阶梯性变化进行分块,算法能够高效计算一系列数值的总和。特别关注了如何确定每个台阶的左右端点,以及如何利用这些信息来减少计算复杂度。
330

被折叠的 条评论
为什么被折叠?



