Problem Description
小A有一个含有
n
个非负整数的数列与
m
个区间。每个区间可以表示为
li,ri
。
它想选择其中 k 个区间, 使得这些区间的交的那些位置所对应的数的和最大。
例如样例中,选择 [2,5] 与 [4,5] 两个区间就可以啦。
它想选择其中 k 个区间, 使得这些区间的交的那些位置所对应的数的和最大。
例如样例中,选择 [2,5] 与 [4,5] 两个区间就可以啦。
Input
多组测试数据
第一行三个数 n,k,m(1≤n≤100000,1≤k≤m≤100000) 。
接下来一行 n 个数 ai ,表示lyk的数列 (0≤ai≤109) 。
接下来 m 行,每行两个数 li,ri ,表示每个区间 (1≤li≤ri≤n) 。
第一行三个数 n,k,m(1≤n≤100000,1≤k≤m≤100000) 。
接下来一行 n 个数 ai ,表示lyk的数列 (0≤ai≤109) 。
接下来 m 行,每行两个数 li,ri ,表示每个区间 (1≤li≤ri≤n) 。
Output
一行表示答案
Sample Input
5 2 3 1 2 3 4 6 4 5 2 5 1 4
Sample Output
10
把区间当左边,维护右端点的第k大值即可。
#include<map> #include<set> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<bitset> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int maxn = 2e5 + 10; int n, m, k,x,l,r; LL sum[maxn],ans; int ft[maxn],nt[maxn],u[maxn],sz; int f[maxn<<3]; void insert(int x,int l,int r,int v) { ++f[x]; if (l==r) return; int mid=l+r>>1; if (v<=mid) insert(x<<1,l,mid,v); else insert(x<<1|1,mid+1,r,v); } int get(int x,int l,int r,int v) { if (l==r) return l; int mid=l+r>>1; if (f[x<<1|1]>=v) return get(x<<1|1,mid+1,r,v); else return get(x<<1,l,mid,v-f[x<<1|1]); } int main() { while (~scanf("%d%d%d",&n,&k,&m)) { memset(f,0,sizeof(f)); ans=sum[0]=sz=0; for (int i=1;i<=n;i++) { scanf("%d",&x); sum[i]=sum[i-1]+x; ft[i]=-1; } for (int i=0;i<m;i++) { scanf("%d%d",&l,&r); u[sz]=r; nt[sz]=ft[l]; ft[l]=sz++; } int tot=0; for (int i=1;i<=n;i++) { for (int j=ft[i];j!=-1;j=nt[j]) { tot++; insert(1,1,n,u[j]); } if (tot<k) continue; ans=max(ans,sum[get(1,1,n,k)]-sum[i-1]); } cout<<ans<<endl; } return 0; }