AcWing4655.重新排序

题目

原题链接

参考题解

AcWing4655.重新排序

image

思路

用两个数组,一个数组a来记录原数组,b数组来记录每个数字被计算了多少次,题目中给的是[l,r]区间内的数字求和,也就是每次给的 [l,r]区间内的数字都会被计算一次,即b[l,r]上的数都要+1,不妨用一个差分数组来统计,b[l] ++,b[r+1] --,然后对b这个差分数组求前缀和,所得的前缀和数组就是所要的记录每个数字被统计了多少次的数组

b差分数组求一遍前缀和(还是用b数组存结果),现在得到了两个数组ab

两数组一个是原元素数组,一个是某个数字统计的频数数组
让和最大就要尽可能让数值大的元素的频数大,那就让两个数组都sort一遍

计算i=1naibi就是原始的sum

ab两数组sort得到的结果再计算i=1naibi就是期望最大和的结果ans

最后答案就是anssum

一个数字最多被计算1e5次,所以一个数最大是1e5 * 1e6,和最大是1e5 * 1e6 * 1e5,肯定会爆int,开long long存sum、ans

代码

#include<iostream>
#include<algorithm>

using namespace std;

typedef long long LL;
const int N = 1e5+10;

int a[N],b[N];
LL sum,ans;
int n,m;

int main()
{
    cin >> n ;
    for(int i = 1;i <= n;i ++) cin >> a[i];
    
    cin >> m ;
    for(int i = 1;i <= m;i ++)
    {
        int l,r;
        cin >> l >> r ;
        b[l] ++ ,b[r + 1] -- ;
    }
    
    for(int i = 1;i <= n; i ++)
    {
        b[i] = b[i - 1] + b[i] ;
        sum += (LL) a[i]*b[i] ;
    }
    
    sort(a+1,a+n+1),sort(b+1,b+n+1);
    
    for(int i = 1;i <= n;i ++)
    {
        ans += (LL) a[i]*b[i];
    }
    
    cout << ans - sum;
    
    return 0;
}
posted @   r涤生  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示