其他分享
首页 > 其他分享> > P2261 [CQOI2007]余数求和

P2261 [CQOI2007]余数求和

作者:互联网

P2261 [CQOI2007]余数求和

分析

求的式子为\(ans = \sum_{i=1}^{n} k\%i\),我们首先需要知道的是\(a\%b=a-b*\left \lfloor \frac{a}{b} \right \rfloor\),则式子就变成了。

\[ans = n*k -\sum_{i=1}^{n}i*\left \lfloor \frac{k}{i} \right \rfloor \]

然后\(\left \lfloor \frac{k}{i} \right \rfloor\),可以用整数分块做,这样时间复杂度就降到\(\sqrt{k}\)

中间有一些小的限制,我会在代码中写出来。

Ac_code

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;

int g(int x,int l)//边界为x,该块边界为l
{
    return x/(x/l);
}

int main()
{
    int n,k;cin>>n>>k;
    LL ans = 0;
    if(n>k)
    {
        ans += 1ll*(n-k)*k;
        n = k;
    }
    ans += 1ll*n*k;
    for(int l=1,r;l<=n;l=r+1)
    {
        r = min(g(k,l),n);
        ans -= 1ll*(l+r)*(r-l+1)/2*(k/l);
    }
    cout<<ans<<'\n';
    return 0;
}

标签:lfloor,right,frac,int,P2261,rfloor,ans,余数,CQOI2007
来源: https://www.cnblogs.com/aitejiu/p/16656475.html