HDU-5700-贪心/stl

区间交

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]两个区间就可以啦。
 

 

Input
多组测试数据

第一行三个数n,k,m(1n100000,1km100000)

接下来一行n个数ai,表示lyk的数列(0ai109)

接下来m行,每行两个数li,ri,表示每个区间(1lirin)

 

 

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 }

 

posted @ 2018-05-13 20:27  *zzq  阅读(161)  评论(0编辑  收藏  举报