chenfy27的刷题记录

导航

abc356E Max/Min

给定数组A[N],对所有1<=i<j<=N,计算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;
}

posted on 2024-10-08 20:08  chenfy27  阅读(16)  评论(0)    收藏  举报