【BZOJ 1257】[CQOI2007]余数之和

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

k%i=k-(k/i)*i 则∑k%i = n*k-∑(k/i)*i 因为k/i是整除运算。 所以会有某一段连续的i,它们的k/i的值都是相同的 那么 这一段连续的i用等差数列求和公式O(1)搞一下就好。 (然后i可以直接跳到上界+1

复杂度是根号N级别的。

连续一段的上界注意不要超过n.
超过n就赋值为n就好

【代码】

#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
 
ll n,k,ans;
 
int main()
{
    scanf("%lld%lld",&n,&k);
    ans = n*k;
    if (n > k) n = k;
    ll up = 0;
    for (int i = 1;i <= n;i = up+1){
        ll temp = k/i;
        up = k/temp;
        if (up>=n) up = n;
        //(i,i+1,i+2...up)*temp
        ans-=1LL*(i+up)*(up-i+1)/2*temp;
    }
    printf("%lld\n",ans);
    return 0;
}

posted @ 2018-03-20 10:10  AWCXV  阅读(135)  评论(0编辑  收藏  举报