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; }

本文探讨了一种算法问题:给定一个整数序列及多个区间,在这些区间中选取k个,使它们交集内元素之和达到最大值。文章通过具体示例解释了问题背景,并提供了一段C++代码实现,利用线段树等数据结构优化求解过程。

654

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



