思路:
题目的主要信息:
- 给定n,求,输出答案对998244353取模后的值
- 运算表示向下取整
方法一:暴力法(超时)
具体做法:
遍历1到n,暴力累加答案并取模
class Solution { public: int work(long long n) { long long res = 0; int mod = 998244353; for(long long i = 1; i <= n; i++){ //注意n为long long res = (res + n / i) % mod; //按照公式累加 } return (int)res; } };
复杂度分析:
- 时间复杂度:,一共遍历次
- 空间复杂度:,常数级变量
方法二:整除分块思路
具体做法:
对于整除我们可以发现如下的规律:
因此我们可以对1到n分区间处理,区间内的整除值都是相同的,都等于,而区间我们如果令,就会发现这个区间右边界为,而这段区间的相加结果就是区间长度乘上区间值。
class Solution { public: int work(long long n) { long long res = 0; int mod = 998244353; long long left = 1, right = n; while(left <= n){ right = n / (n / left); //找到相同商数的区间右界 res = (res + (right - left + 1) * (n / left)) % mod; //相同数*区间长度 left = right + 1; //更新左界 } return (int)res; } };
复杂度分析:
- 时间复杂度:,因为对于被除数最多有个不同的商,因为当时,一共最多有个商,而这些商又可以作为除数对应当时的商
- 空间复杂度:,常数级变量