P2261 [CQOI2007]余数求和
关键在于化简公式,题目所求$sum_{i=1}^{n}kmod i$
简化式子,也就是$sum_{i=1}^{n}(k-frac{k}{i} imes k)$
$=n*k-sum_{i=1}^{n}frac{k}{i} imes 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) imes 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 ",ans); return 0; }