题解P2261

原题传送门

最重要的事:long long!!!!!!

首先,题目要求的是\(res=\sum\limits_{i=1}^{n}k\%i\)

可以把\(k\%i\)转化为\(k-i\times\left\lfloor\dfrac{k}{i}\right\rfloor\)

证明:\(\left\lfloor\dfrac{k}{i}\right\rfloor\)是向下取整,所以将小数点部分都去掉,去掉\(\dfrac{k\%i}{i}\)的值

所以\(\left\lfloor\dfrac{k}{i}\right\rfloor=\dfrac{k-k\%i}{i}\)

所以\(k\%i=k-(k-k\%i)=k-i\times\dfrac{k-k\%i}{i}=k-i\times\left\lfloor\dfrac{k}{i}\right\rfloor\)

然后,写代码了:

#include<iostream>
using namespace std;
typedef long long ll;
ll n,k,res;
inline void solve(){
    res=n*k,n=min(n,k);//当i>k时,k/i为0,会/0,故取min
    ll i=1,j;
    while(i<=n){
        j=min(k/(k/i),n);//这里可能会超过n,所以取min
        res-=(k/i)*(j-i+1)*(i+j)>>1;
        i=j+1;
    }
    cout<<res;
}
int main(){
    cin>>n>>k;
    solve();
    return 0;
}

P.S.这个题要注意的地方挺多,有意思的一道题

猜你喜欢

转载自www.cnblogs.com/RadestionAdtinium/p/13196563.html