题解 P2261 [CQOI2007]余数求和

Posted colazcy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P2261 [CQOI2007]余数求和相关的知识,希望对你有一定的参考价值。

题目链接

Solution [CQOI2007]余数求和

题目大意:给定\(n,k\),求\(\sum_i = 1^nk \bmod i\)

解析:我们考虑大力化柿子

\[\sum_i = 1^nk \bmod i\]
\[=\sum_i = 1^nk-i \times \lfloor \fracki \rfloor\]

\[=nk-\sum_i = 1^ni \times\lfloor \fracki \rfloor\]

然后我们发现右边\(\sum_i = 1^ni \times\lfloor \fracki \rfloor\)这个东西不是很好求,跑去现学整除分块,我们发现\(\lfloor \fracki \rfloor\)这个东西是可以分成很多块,每一块内的\(\lfloor \fracki \rfloor\)是不变的,我们将其提出,就是一个等差数列求和了

对于一个左端点为\(l\),对于\(\lfloor \fracki \rfloor\)分块的块,其右端点为\(r = \lfloor \frack\lfloor \frackl \rfloor \rfloor\),假如\(\lfloor \frackl \rfloor = 0\)那么\(r = n\)(至于怎么证明这玩意儿我还真不会)

程序就很好写了,注意\(r\)不能超过\(n\)

代码:

#include <algorithm>
#include <cstdio>
using namespace std;
long long n,k,ans;
int main()
    scanf("%lld %lld",&n,&k);
    ans = n * k;
    for(long long l = 1,r;l <= n;l = r + 1)
        r = (k / l == 0) ? n : min(n,k / (k / l)),ans -= (((l + r) * (r - l + 1)) >> 1) * (k / l);
    return printf("%lld\n",ans),0;

以上是关于题解 P2261 [CQOI2007]余数求和的主要内容,如果未能解决你的问题,请参考以下文章

p2261 [CQOI2007]余数求和

P2261 [CQOI2007]余数求和

P2261 [CQOI2007]余数求和

P2261 [CQOI2007]余数求和

P2261 [CQOI2007]余数求和

洛谷P2261[CQOI2007]余数求和