题意:小A有一个含有
n
个非负整数的数列与
m
个区间。每个区间可以表示为
li,ri
。
它想选择其中 k 个区间, 使得这些区间的交的那些位置所对应的数的和最大。
它想选择其中 k 个区间, 使得这些区间的交的那些位置所对应的数的和最大。
题目分析:求前缀和,枚举左端点,用multiset维护右端点,因为set自带排序,所以set的第一个元素就是当前最小的右端点,而枚举的i就是当前最大的左端点,然后更新答案
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-10
#define maxn 100010
#define MOD 1000000007
struct node
{
int l,r;
bool operator < (const node &a) const
{
return l < a.l || (l == a.l && r < a.r);
}
}cnt[maxn];
int n,k,m;
long long a[maxn],sum[maxn];
int main()
{
while(scanf("%d%d%d",&n,&k,&m) != EOF)
{
sum[0] = 0;
for(int i = 1; i <= n; i++)
{
scanf("%lld",&a[i]);
sum[i] = sum[i-1] + a[i];
}
for(int i = 0; i < m; i++)
scanf("%d%d",&cnt[i].l,&cnt[i].r);
sort(cnt,cnt+m);
multiset<int> ml;
for(int i = 0; i < k; i++)
ml.insert(cnt[i].r);
long long ans = max((long long)0,sum[*ml.begin()]-sum[cnt[k-1].l-1]);
for(int i = k; i < m; i++)
{
ml.erase(ml.begin());
ml.insert(cnt[i].r);
ans = max(ans,sum[*ml.begin()]-sum[cnt[i].l-1]);
}
printf("%I64d\n",ans);
}
return 0;
}