区间交
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1390 Accepted Submission(s): 528
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
Source
一开始的思路其实就是对的,为啥一直错因为tm我用的头文件有一句 #define LL unsigned long long ,改成 long long 就好了= =
可以对左端点升序排列,然后枚举当前线段作为左端点,要从他前面挑出k个区间使得价值最大,我们只需要维护一个最大的最小右端点即可(stl)。如果有些右端点与当前线段无交集显然也不会和后面的有,直接pop,如果之后堆里的点还是大于k个就继续pop直至剩下k个,队首显然就是最优的。
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cstdio> 5 #include<stack> 6 #include<set> 7 #include<map> 8 #include<cmath> 9 #include<ctime> 10 #include<time.h> 11 #include<algorithm> 12 #include<bits/stdc++.h> 13 using namespace std; 14 #define mp make_pair 15 #define pb push_back 16 #define debug puts("debug") 17 #define LL long long 18 #define ULL unsigned long long 19 #define pii pair<int,int> 20 #define eps 1e-10 21 #define inf 0x3f3f3f3f 22 23 LL a[101010]; 24 struct node{ 25 int l,r; 26 }P[101010]; 27 bool cmp(node A,node B){ 28 return A.l<B.l; 29 } 30 31 int main(){ 32 int n,k,m,i,j; 33 cin>>n>>k>>m; 34 for(i=1;i<=n;++i) 35 scanf("%lld",a+i),a[i]+=a[i-1]; 36 for(i=1;i<=m;++i) 37 scanf("%d%d",&P[i].l,&P[i].r); 38 sort(P+1,P+1+m,cmp); 39 LL ans=0; 40 priority_queue<int,vector<int>,greater<int> >q; 41 for(i=1;i<=m;++i){ 42 q.push(P[i].r); 43 while(q.size()>k || q.top()<P[i].l ) q.pop(); 44 if(q.size()==k&&q.top()>=P[i].l){ 45 ans=max(ans,a[q.top()]-a[P[i].l-1]); 46 } 47 } 48 cout<<ans<<endl; 49 return 0; 50 }