重新排序
题目:重新排序
【问题描述】
给定一个数组 $A$ 和一些查询 $L_i, R_i$,求数组中第 $L_i$ 至第 $R_i$ 个元素之和。
小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?
【输入格式】
输入第一行包含一个整数 $n$。
第二行包含 $n$ 个整数 $A_1, A_2, \cdots, A_n$。相邻两个整数之间用一个空格分隔。
第三行包含一个整数 $m$ 表示查询的数目。
接下来 $m$ 行,每行包含两个整数 $L_i, R_i$。相邻两个整数之间用一个空格分隔。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
Plaintext5
1 2 3 4 5
2
1 3
2 5
【样例输出】
Plaintext4
【样例说明】
原来的和为 $6 + 14 = 20$,重新排列为 $(1, 4, 5, 2, 3)$ 后和为 $10 + 14 = 24$,增加了 4。
【评测用例规模与约定】
对于所有评测用例,$1 \le n, m \le 10^5, 1 \le A_i \le 10^6, 1 \le L_i \le R_i \le 10^6$。
想要查询的部分和最大,我们可以统计每个位置被统计的次数然后被查询次数越多的位置放的数越大,这样就可以使查询部分和最大。
using namespace std;
int main()
{
int n,m,total=0,atotal=0;
cin>>n;
vector<int>arr(n+1,0);
vector<int>sum(n+1,0);
for(int i=1;i<=n;i++)
{
cin>>arr[i];
sum[i]=arr[i];
}
for(int i=2;i<=n;i++)
sum[i]+=sum[i-1];
cin>>m;
vector<int>num(n+2,0);
for(int i=1;i<=m;i++)
{
int l,r;
cin>>l>>r;
num[l]+=1;
num[r+1]-=1;
total+=sum[r]-sum[l-1];
}
for(int i=2;i<=n;i++)
num[i]+=num[i-1];
sort(num.begin()+1,num.end()-1);
sort(arr.begin()+1,arr.end());
for(int i=1;i<=n;i++)
atotal+=num[i]*arr[i];
cout<<atotal-total;
}
