编程语言
首页 > 编程语言> > 《算法竞赛进阶指南》0x32 T2 余数之和

《算法竞赛进阶指南》0x32 T2 余数之和

作者:互联网

题目传送门

题目描述

给出正整数 n n n和 k k k,计算 ( k m o d 1 ) + ( k m o d 2 ) + ( k m o d 3 ) + … + ( k m o d n ) (kmod1)+(k mod 2)+(k mod 3)+…+(k mod n) (kmod1)+(kmod2)+(kmod3)+…+(kmodn)的值。

输入格式

输入仅一行,包含两个整数 n n n, k k k。

输出格式

输出仅一行,即 ( k m o d 1 ) + ( k m o d 2 ) + ( k m o d 3 ) + … + ( k m o d n ) (kmod1)+(k mod 2)+(k mod 3)+…+(k mod n) (kmod1)+(kmod2)+(kmod3)+…+(kmodn)的值。

数据范围

1 ≤ n , k ≤ 1 0 9 1≤n,k≤10^9 1≤n,k≤109

输入样例

5 3

输出样例

7

题解 O ( k ) O(\sqrt k) O(k ​)

很简单的一个道理 k k k% i i i= k − ⌊ k / i ⌋ × i k-\lfloor k/i\rfloor \times i k−⌊k/i⌋×i
所以题目要求的式子就可以转化为 n × k − n\times k- n×k− ∑ i = 1 n ⌊ k / i ⌋ × i \sum_{i = 1}^{n}\lfloor k/i\rfloor \times i ∑i=1n​⌊k/i⌋×i

接下来我们拿n= 9 ,k = 4 为例分析下k/i:
  4/1 4/2 4/3 4/4 4/5 4/6 4/7 4/8 4/9
  4  2  1  1  0  0  0  0  0
所以最后的结果就是
9 ∗ 4 − 4 ∗ 1 − 2 ∗ 2 − 1 ∗ ( 3 + 4 ) − 0 ∗ ( 5 + 6 + 7 + 8 + 9 ) 9*4-4*1-2*2-1*(3+4)-0*(5+6+7+8+9) 9∗4−4∗1−2∗2−1∗(3+4)−0∗(5+6+7+8+9)
用l和r来表示一个连续区间的左端点和右端点,再通过等差数列通项公式 ( l + r ) ∗ ( r − l + 1 ) / 2 (l+r)*(r-l+1)/2 (l+r)∗(r−l+1)/2求出这一段数字的总和再乘上 ( k / l ) (k/l) (k/l)。
通过以上这种方式就可以避免遍历 1 − n 1-n 1−n,大大减少循环次数

code
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,k;
	cin>>n>>k;
	int r;
	long long ans;
	ans=(long long)n*k;
	for(int l=1;l<=n;l=r+1)
	{
		if(k/l==0) break;//超出范围,退出循环
		r=min(k/(k/l),n);//求出右端点,再与n求最小值,防止超出范围
		ans-=(long long)(k/l)*(l+r)*(r-l+1)/2;//公式
	}
	cout<<ans;
	return 0;
 } 

标签:进阶,int,ans,T2,long,times,0x32,kmod1,mod
来源: https://blog.csdn.net/weixin_55355427/article/details/114291723