zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
    POJ 1088 滑雪 DP
    UVA 11584 最短回文串划分 DP
    POJ 2531 Network Saboteur DFS+剪枝
    UVa 10739 String to Palindrome 字符串dp
    UVa 11151 Longest Palindrome 字符串dp
    UVa 10154 Weights and Measures dp 降维
    UVa 10271 Chopsticks dp
    UVa 10617 Again Palindrome 字符串dp
    UVa 10651 Pebble Solitaire 状态压缩 dp
  • 原文地址:https://www.cnblogs.com/hhxj/p/7103719.html
Copyright © 2011-2022 走看看