4655. 重新排序
4655. 重新排序
给定一个数组 A
和一些查询 Li,Ri
,求数组中第 Li
至第 Ri
个元素之和。
小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。
小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?
输入格式
输入第一行包含一个整数 n
。
第二行包含 n
个整数 A1,A2,⋅⋅⋅,An
,相邻两个整数之间用一个空格分隔。
第三行包含一个整数 m
表示查询的数目。
接下来 m
行,每行包含两个整数 Li、Ri
,相邻两个整数之间用一个空格分隔。
输出格式
输出一行包含一个整数表示答案。
数据范围
对于 30%
的评测用例,n,m≤50
;
对于 50%
的评测用例,n,m≤500
;
对于 70%
的评测用例,n,m≤5000
;
对于所有评测用例,1≤n,m≤105
,1≤Ai≤106
,1≤Li≤Ri≤n
。
输入样例:
5
1 2 3 4 5
2
1 3
2 5
输出样例:
4
样例解释
原来的和为 6+14=20
,重新排列为 (1,4,5,2,3)
后和为 10+14=24
,增加了 4
。
前缀和+差分
思路 :让大的数字,尽可能多的出现即可
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int N=100010;
int num[N];
ll presum[N];
int cnt[N];
int fin_num[N];
int L[N];
int R[N];
map<int,int>dict;
struct data{
int cnt;
int num;
};
struct data order[N];
bool cmp(struct data o1,struct data o2){
return o1.cnt>o2.cnt;
}
int main()
{
int n;
scanf("%d",&n);
presum[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
presum[i]=presum[i-1]+num[i];
}
int m;
scanf("%d",&m);
ll sum_0=0,sum_1=0;
for(int i=1;i<=m;i++){
scanf("%d%d",&L[i],&R[i]);
dict[L[i]]++;
dict[R[i]+1]--;
sum_0+=(presum[R[i]]-presum[L[i]-1]);
}
sort(num+1,num+n+1,greater<int>());
cnt[0]=0;
for(int i=1;i<=n;i++){
cnt[i]=cnt[i-1]+dict[i];
}
for(int i=1;i<=n;i++){
order[i].cnt=cnt[i];
order[i].num=i;
}
sort(order+1,order+n+1,cmp);
// for(int i=1;i<=n;i++) cout<<num[i]<<" ";
// cout<<endl;
// for(int i=1;i<=n;i++) cout<<order[i].cnt<<":"<<order[i].num<<" ";
// cout<<endl;
for(int i=1;i<=n;i++){
fin_num[order[i].num]=num[i];
}
presum[0]=0;
for(int i=1;i<=n;i++) presum[i]=presum[i-1]+fin_num[i];
for(int i=1;i<=m;i++){
sum_1+=(presum[R[i]]-presum[L[i]-1]);
}
cout<<sum_1-sum_0;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具