hdu 5700

                  区间交

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1162    Accepted Submission(s): 456


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
思路:我们按照右区间从大到小排序,那么我们可以枚举当前K个及以上的区间,从这里面选取K个,这K个里面左端点肯定是越小越好,那么就是当前的第K小了,可用线段树来维护更新
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1e5+10;
 5 
 6 struct node{
 7     int x,y;
 8 }a[N];
 9 ll s[N];
10 int n,k,m;
11 bool cmp(node p,node q){
12     return p.y>q.y;
13 }
14 
15 struct nn{
16     int l,r;
17     ll sum;
18 }e[N*4];
19 void build(int x,int L,int R){
20     e[x].l=L;e[x].r=R;
21     if(L==R){
22         e[x].sum=0;return ;
23     }
24     int mid=(L+R)>>1;
25     build(2*x,L,mid);
26     build(2*x+1,mid+1,R);
27     e[x].sum=e[x*2].sum+e[2*x+1].sum;
28 }
29 void update(int v,int x){
30     if(e[x].l==e[x].r){
31         e[x].sum++;return ;
32     }
33     int mid=(e[x].l+e[x].r)>>1;
34     if(v<=mid)  update(v,2*x);
35     else update(v,2*x+1);
36     e[x].sum=e[x*2].sum+e[2*x+1].sum;
37 }
38 
39 int query(int v,int x){
40     if(e[x].l==e[x].r){
41         return e[x].l;
42     }
43     if(e[2*x].sum>=v) query(v,2*x);
44     else query(v-e[x*2].sum,2*x+1);
45 }
46 int main(){
47     while(scanf("%d%d%d",&n,&k,&m)!=EOF){
48     ll x;
49     build(1,1,n);
50     for(int i=1;i<=n;i++){
51         scanf("%lld",&x);s[i]=s[i-1]+x;
52     }
53     for(int i=1;i<=m;i++){
54         scanf("%d%d",&a[i].x,&a[i].y);
55     }
56     sort(a+1,a+1+m,cmp);
57     for(int i=1;i<=k-1;i++){
58         update(a[i].x,1);
59     }
60     ll Max=0;
61     for(int i=k;i<=m;i++){
62         update(a[i].x,1);
63        // cout<<e[1].sum<<endl;
64         int xx=query(k,1);
65         //cout<<xx<<" "<<a[i].y<<endl;
66         if(xx<=a[i].y){
67             Max=max(Max,s[a[i].y]-s[xx-1]);
68         }
69     }
70     cout<<Max<<endl;
71     }
72     return 0;
73 }

 

posted on 2017-07-01 22:42  hhhhx  阅读(160)  评论(0编辑  收藏  举报

导航