排列中的每个数对答案的贡献是它被查询的次数乘以它自身,因此,要最大化答案,应该在被查询次数较多的位置放置较大的数。
用差分和线段树等方法统计每个位置被查询的次数,对每个位置被查询的次数排序,在较大的位置放置排列中较大的数,再计算答案即可。
时间复杂度为 O(n log n)。
#include <iostream> #include <vector> #include <algorithm> const int maxn = 2e5+7; using ll = long long; ll n, m, l, r, cur = 0, res = 0, cnt[2][maxn], ans[maxn]; int main(int argc, char *argv[]) { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cin >> n >> m; for (int i = 0; i < m; i++) { std::cin >> l >> r; cnt[0][l]++; cnt[1][r]--; } for (int i = 1; i <= n; i++) { cur += cnt[0][i]; ans[i] = cur; cur += cnt[1][i]; } std::sort(ans+1, ans+n+1); for (ll i = 1; i <= n; i++) { res += i * ans[i]; } std::cout << res << '\n'; }