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;
}