1862.sum-of-floored-pairs
Statement
Metadata
- Link: 向下取整数对和
- Difficulty: Hard
- Tag:
数组
数学
二分查找
前缀和
给你一个整数数组 nums
,请你返回所有下标对 0 <= i, j < nums.length
的 floor(nums[i] / nums[j])
结果之和。由于答案可能会很大,请你返回答案对109 + 7
取余 的结果。
函数 floor()
返回输入数字的整数部分。
示例 1:
输入:nums = [2,5,9]
输出:10
解释:
floor(2 / 5) = floor(2 / 9) = floor(5 / 9) = 0
floor(2 / 2) = floor(5 / 5) = floor(9 / 9) = 1
floor(5 / 2) = 2
floor(9 / 2) = 4
floor(9 / 5) = 1
我们计算每一个数对商向下取整的结果并求和得到 10 。
示例 2:
输入:nums = [7,7,7,7,7,7,7]
输出:49
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105
Metadata
- Link: Sum of Floored Pairs
- Difficulty: Hard
- Tag:
Array
Math
Binary Search
Prefix Sum
Given an integer array nums
, return the sum of floor(nums[i] / nums[j])
for all pairs of indices 0 <= i, j < nums.length
in the array. Since the answer may be too large, return it modulo 109 + 7
.
The floor()
function returns the integer part of the division.
Example 1:
Input: nums = [2,5,9]
Output: 10
Explanation:
floor(2 / 5) = floor(2 / 9) = floor(5 / 9) = 0
floor(2 / 2) = floor(5 / 5) = floor(9 / 9) = 1
floor(5 / 2) = 2
floor(9 / 2) = 4
floor(9 / 5) = 1
We calculate the floor of the division for every pair of indices in the array then sum them up.
Example 2:
Input: nums = [7,7,7,7,7,7,7]
Output: 49
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
Tutorial
我们要求:
其中,
复杂度不对的做法
- 考虑枚举
,然后数论分块求和。 - 时间复杂度
。
我们考虑
形式化的表达:
所以时间复杂度是调和级数,为
Solution
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define endl "\n"
#define fi first
#define se second
#define all(x) begin(x), end(x)
#define rall rbegin(a), rend(a)
#define bitcnt(x) (__builtin_popcountll(x))
#define complete_unique(a) a.erase(unique(begin(a), end(a)), end(a))
#define mst(x, a) memset(x, a, sizeof(x))
#define MP make_pair
using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
using VLL = std::vector<ll>;
using VI = std::vector<int>;
using PII = std::pair<int, int>;
using PLL = std::pair<ll, ll>;
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
const ll mod = 1e9 + 7;
template <typename T, typename S>
inline bool chmax(T &a, const S &b) {
return a < b ? a = b, 1 : 0;
}
template <typename T, typename S>
inline bool chmin(T &a, const S &b) {
return a > b ? a = b, 1 : 0;
}
#ifdef LOCAL
#include <debug.hpp>
#else
#define dbg(...)
#endif
// head
class Solution {
public:
int sumOfFlooredPairs(vector<int> &nums) {
static const int mod = 1e9 + 7;
const int N = *max_element(nums.begin(), nums.end());
vector<int> cnt(N + 10, 0), sum(N + 10, 0);
for (const auto &v : nums) {
++cnt[v];
}
for (int i = 1; i <= N; i++) {
sum[i] = sum[i - 1] + cnt[i];
}
int res = 0;
for (int i = 1; i <= N; i++) {
if (cnt[i] == 0) {
continue;
}
int cur_res = 0;
for (int d = 1; i * d <= N; d++) {
int up = min(N + 1, i * (d + 1));
int down = i * d;
cur_res += 1ll * (sum[up - 1] - sum[down - 1]) * d % mod;
if (cur_res >= mod) {
cur_res -= mod;
}
}
res += 1ll * cnt[i] * cur_res % mod;
if (res >= mod) {
res -= mod;
}
}
return res;
}
};
#ifdef LOCAL
int main() {
return 0;
}
#endif
最后更新: October 11, 2023