题意:
输入正整数n和k(范围均为1e9),求∑(k mod i),i从1~n
解法:
首先这道题直接暴力亲测会超时。
之后我们写几组数据之后可以发现当k/i的商相同的时候他们的余数成一个等差数列,而且数列首相是q,公差是p,项的个数是余数/商。
具体写法网上面有分情况讨论的,但是较为繁琐,这里LRJ的板子感觉写法就很精炼。
我们从左到右依次枚举每一项i(核心思想是减少i的枚举个数),计算出k除以这个数的商和余数, 如果这个商是0,说明此时的i已经大于k;如果不为0(即大于0),即来计算等差的数列的值。
如果k%i==0,则项的个数为0,计算和之后为0,其他情况就很正常了。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 ll series_sum(int p, int d, int n) { return (ll)(2 * p - n*d)*(n + 1) / 2; } 6 int main() { 7 int n, k; 8 while (scanf("%d%d", &n, &k) != EOF) { 9 ll ans = 0, i = 1; 10 while (i <= n) { 11 int p = k / i, q = k%i; 12 int cnt = n - i; 13 if (p > 0)cnt = min(cnt, q / p);//计算项的个数,避免超出n的范围 14 ans += series_sum(q, p, cnt); 15 i += cnt + 1; 16 } 17 printf("%lld\n", ans); 18 } 19 return 0; 20 }
原文地址:https://www.cnblogs.com/romaLzhih/p/9515216.html
时间: 2024-10-29 04:15:36