给定数组A[N],对所有i<j,计算max(A[i],A[j])/min(A[i],A[j])之和,除法为向下取整。
2<=N<=2E5; 1<=A[i]<=1E6
分析:排序不影响结果,先对A[N]排序和计数,然后枚举每个数作为除数时产生的商,注意数可以重复,因此重复的数要单独统计,以及商为1的那部分也要单独算。
#include <bits/stdc++.h>
using i64 = long long;
const int maxn = 1000000;
void solve() {
int N;
std::cin >> N;
std::vector<int> cnt(maxn + 1), pre(maxn + 1);
for (int i = 0; i < N; i++) {
int x;
std::cin >> x;
cnt[x] += 1;
}
for (int i = 1; i <= maxn; i++) {
pre[i] = pre[i-1] + cnt[i];
}
auto sum = [&](int l, int r) {
return l <= r ? pre[r] - pre[l - 1] : 0;
};
i64 ans = 0;
for (int i = 1; i <= maxn; i++) {
if (cnt[i] == 0) {
continue;
}
ans += 1LL * cnt[i] * (cnt[i] - 1) / 2;
ans += 1LL * cnt[i] * sum(i + 1, std::min(2 * i - 1, maxn));
for (int j = 2; j * i <= maxn; j++) {
int L = j * i;
int R = j * i + i - 1;
int z = sum(L, std::min(R, maxn));
ans += 1LL * cnt[i] * j * z;
}
}
std::cout << ans << "\n";
}
int main() {
std::cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}
标签:std,cnt,Min,int,Max,abc365E,long,maxn
From: https://www.cnblogs.com/chenfy27/p/18452393