基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
小A有一个含有n个非负整数的数列与m个区间,每个区间可以表示为li,ri。
它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大。(是指k个区间共同的交,即每个区间都包含这一段,具体可以参照样例)
在样例中,5个位置对应的值分别为1,2,3,4,6,那么选择[2,5]与[4,5]两个区间的区间交为[4,5],它的值的和为10。
Input
第一行三个数n,k,m(1<=n<=100000,1<=k<=m<=100000)。 接下来一行n个数ai,表示小A的数列(0<=ai<=10^9)。 接下来m行,每行两个数li,ri,表示每个区间(1<=li<=ri<=n)。
Output
一行表示答案
Input示例
5 2 3 1 2 3 4 6 4 5 2 5 1 4
Output示例
10
题解:按照区间左端点从小到大排序,从左至右枚举区间,线段树维护右端点,根据贪心思想,一定是找右端点第k大的。
#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=a-1;i>=b;--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
#define add(x,y) x=((x)+(y)>=mod)?(x)+(y)-mod:(x)+(y)
#define sub(x,y) x=((x)-(y)<0)?(x)-(y)+mod:(x)-(y)
#define eps 1e-10
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int MX = 1e5 + 5;
const int mod = 1e9 + 9;
int a[MX];
ll pre[MX];
struct Line {
int l, r;
bool operator<(const Line& _A)const {
if(l != _A.l) return l < _A.l;
return r < _A.r;
}
} b[MX];
int mx[MX << 2];
void PushUP(int rt) {
mx[rt] = mx[rt << 1] + mx[rt << 1 | 1];
}
void update(int p, int l, int r, int rt) {
if(l == r) {
mx[rt]++;
return;
}
int m = (l + r) >> 1;
if(p <= m) update(p, lson);
else update(p, rson);
PushUP(rt);
}
int query(int k, int l, int r, int rt) {
if(l == r) return l;
int m = (l + r) >> 1;
if(mx[rt << 1 | 1] >= k) return query(k, rson);
return query(k - mx[rt << 1 | 1], lson);
}
int main() {
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n, k, m; cin >> n >> k >> m;
rep(i, 1, n + 1) cin >> a[i];
rep(i, 1, n + 1) pre[i] = pre[i - 1] + a[i];
rep(i, 1, m + 1) cin >> b[i].l >> b[i].r;
sort(b + 1, b + m + 1);
ll ans = 0;
rep(i, 1, k) update(b[i].r, 1, n, 1);
rep(i, k, m + 1) {
update(b[i].r, 1, n, 1);
int l = b[i].l, r = query(k, 1, n, 1);
if(l <= r) ans = max(ans, pre[r] - pre[l - 1]);
}
cout << ans << endl;
return 0;
}