HDU 5700 区间交(线段树)
题目链接 区间交
给定n和k,求k个区间,使得这K个区间的交集的数的和最大。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define lson i << 1, L, mid
#define rson i << 1 | 1, mid + 1, R
typedef long long LL;
const int N = 200010;
struct node{
int l, r;
friend bool operator < (const node &a, const node &b){
return a.l < b.l;
}
} a[N];
int tree[N << 2];
int n, k, m;
LL sum[N], ans, x;
void pushup(int i){ tree[i] = tree[i << 1] + tree[i << 1 | 1]; }
void update(int i, int L, int R, int x){
if (L == R){ ++tree[i]; return;}
int mid = (L + R) >> 1;
if (x <= mid) update(lson, x); else update(rson, x);
pushup(i);
}
int query(int i, int L, int R, int x){
if (L == R) return L;
int mid = (L + R) >> 1;
if (tree[i << 1 | 1] >= x) return query(rson, x);
else return query(lson, x - tree[i << 1 | 1]);
}
int main(){
while (~scanf("%d%d%d", &n, &k, &m)){
sum[0] = 0; ans = 0;
memset(tree, 0, sizeof tree);
rep(i, 1, n){
scanf("%lld", &x);
sum[i] = sum[i - 1] + x;
}
rep(i, 1, m) scanf("%d%d", &a[i].l, &a[i].r);
sort(a + 1, a + m + 1);
dec(i, k, 1) update(1, 1, n, a[i].r);
a[m + 1].r = 1;
rep(i, k, m){
int pos = query(1, 1, n, k);
if (pos >= a[i].l) ans = max(ans, sum[pos] - sum[a[i].l - 1]);
update(1, 1, n, a[i + 1].r);
}
printf("%lld\n", ans);
}
return 0;
}

浙公网安备 33010602011771号