AcWing 4655. 重新排序
原题链接
中等
作者:
无双飞怪
,
2024-04-17 18:07:37
,
所有人可见
,
阅读 1
不开long long 见祖宗
凡是两个数做乘法记得考虑long long!!!
先正常算
然后思考:什么时候能让重新排列之后的数组与原数组在相同的区间中之差最大?
答案:让出现次数最多的端点排列到最后 出现次数最多的端点与数组中最大的数相乘这个结果不就最大吗
故:先正常算和(注意优化 由于m可能很大 所以可以先算区间端点出现多少次(先差分后前缀和) 然后用端点出现的次数去乘每个端点的数)
然后排序 两个数组都排序 大的数去乘次数最多的端点
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int b[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int m;
cin>>m;
long long sumn=0;
while(m--)
{
int l,r;
cin>>l>>r;
b[l]++,b[r+1]--;
}
for(int i=1;i<=n;i++) b[i]+=b[i-1];
for(int i=1;i<=n;i++) sumn+=(long long)b[i]*a[i];//千万注意这里 会爆
sort(a+1,a+n+1);
sort(b+1,b+n+1);
long long tmp=0;
for(int i=1;i<=n;i++) tmp+=(long long)a[i]*b[i];//还有这里
cout<<tmp-sumn;
return 0;
}