小A有一个含有n个非负整数的数列与m个区间。每个区间可以表示为
[l,r]
它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大。
例如样例中,选择 [2,5] 与 [4,5]
它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大。
例如样例中,选择 [2,5] 与 [4,5]
两个区间就可以啦。
Sample Input
5 2 3 1 2 3 4 6 4 5 2 5 1 4
Sample Output
10
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#define LL __int64
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
LL sum[100010],arr[100010];
vector<LL >q[100010];
multiset<LL >S;
int main(){
LL n,m,j,i,k;
while(~scanf("%I64d%I64d%I64d",&n,&k,&m)){
for(i = 0;i <=n;++ i){
sum[i] = 0;q[i].clear();
}
S.clear();
multiset<LL>::iterator cnt;
for(i = 1;i <= n;++ i){
scanf("%I64d",&arr[i]);
sum[i]= sum[i-1] + arr[i];
}
LL a,b,ma=0,ans = 0;
while(m--){
scanf("%I64d%I64d",&a,&b);
ma = max(ma,a);
q[a].push_back(b);
}
for(i = 1;i <= ma;++ i){
LL len = q[i].size();
for(j = 0;j < len;++ j){
LL u = q[i][j];
S.insert(u);
}
while(S.size()> k){
S.erase(S.begin());
}
len = S.size();
if(len==k&&*S.begin()>=i)
ans = max(ans,sum[*S.begin()] - sum[i-1] );
}
printf("%I64d\n",ans);
}
return 0;
}
本文介绍了一种解决区间交集求和问题的算法思路,通过预处理前缀和并利用multiset数据结构来高效地找出最佳的区间组合,以实现最大的交集数值之和。
&spm=1001.2101.3001.5002&articleId=51481595&d=1&t=3&u=6145c165949f4ea59a6c3a4ddc59365e)
778

被折叠的 条评论
为什么被折叠?



