洛谷——P2261 [CQOI2007]余数求和

P2261 [CQOI2007]余数求和

 

关键在于化简公式,题目所求$\sum_{i=1}^{n}k\mod i$

简化式子,也就是$\sum_{i=1}^{n}(k-\frac{k}{i}\times k)$

$=n*k-\sum_{i=1}^{n}\frac{k}{i}\times k$

 

$⌊ \frac{m}{k}⌋$ 共有 $O( √ m)$ 种取值,直接计算。总时间复杂度 $O( √ m)$

 

观察下图:

 

你会发现$\frac{k}{i}$是有规律的,或者说相同的紧挨着,分布在同一个块中

 

确定$\frac{k}{i}$取值相同的区间$[l,r]$,$r=min(n,k/(k/l))$

$k/l$代表这一部分的取值,$k/(k/l)$就是区间的右端点

 

确定了区间,那么根据等差数列求和公式$\frac{(S1+Sn)\times n}{2}$

 

#include<bits/stdc++.h>

#define LL long long
using namespace std;

LL n,k;

int main()
{
    scanf("%lld%lld",&n,&k);
    LL ans=n*k;
    for(LL l=1,r;l<=n;l=r+1){
        if(k/l!=0) r=min(k/(k/l),n);
        else r=n;
        ans-=(k/l)*(r-l+1)*(l+r)/2;
    } 
    
    printf("%lld\n",ans);
    
    return 0;
}

 

posted @ 2018-10-15 16:02  清风我已逝  阅读(158)  评论(0编辑  收藏  举报