二刷重排 第一次题解:蓝桥杯 重新排序(Acwing 4655)_skyang.的博客-CSDN博客
思路:先读取区间,计算每个位置被统计的次数,让被统计次数多的位置填上尽可能大的数。
因此直接计算重排前的和,可以通过前缀和差分快速求得。
重排后的和,即可将数组排序、统计次数排序 相乘求和可得。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100005;
int n,m;
ll a[N],cnt[N],b[N];
ll sum1,sum2;
int l,r;
int main()
{
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i) b[i]=b[i-1]+a[i];
cin>>m;
for(int i=1;i<=m;++i)
{
cin>>l>>r;
sum1+=b[r]-b[l-1];
cnt[l]++;
cnt[r+1]--;
}
for(int i=1;i<=n;++i) cnt[i]+=cnt[i-1];
sort(a+1,a+n+1);
sort(cnt+1,cnt+n+1);
for(int i=1;i<=n;i++) sum2+=a[i]*cnt[i];
cout<<sum2-sum1<<endl;
return 0;
}