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): 567    Accepted Submission(s): 279


    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
     
     
    解题思路:首先排序右端点从小到大(也可以排序左端点,也可以从大到小排序,看怎么处理了),然后枚举右端点(保证所枚举的那个端点最少有k个区间可以覆盖)作为所求的交区间的右端点,这时候需要求出交区间的左端点,我们可以知道,右端点确定下,如果左端点越靠左,这个区间的范围约大。为了保证所交区间有k个,我们需要找到第k小的左端点,为了保证我枚举的右端点肯定是交区间的右端点,我们必须边枚举,边单点更新左端点。
     
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<string>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<map>
    #include<vector>
    #include<set>
    using namespace std;
    typedef long long LL;
    #define mid (L+R)/2
    #define lson rt*2,L,mid
    #define rson rt*2+1,mid+1,R
    #pragma comment(linker, "/STACK:102400000,102400000")
    const int maxn = 1e5+300;
    const int INF = 0x3f3f3f3f;
    typedef long long  LL;
    typedef unsigned long long ULL;
    LL presum[maxn];
    struct Interval{
        int l, r;
    }intervals[maxn];
    struct Seg{
        int cover;
    }segs[maxn*4];
    bool cmp(Interval a, Interval b){
        return a.r < b.r;           //
    }
    void PushUp(int rt){
        segs[rt].cover = segs[rt*2].cover + segs[rt*2+1].cover;
    }
    void buildtree(int rt,int L,int R){
        if(L == R){
            segs[rt].cover = 0;
            return;
        }
        buildtree(lson);
        buildtree(rson);
        PushUp(rt);
    }
    void Update(int rt,int L,int R,int id){
        if(L == R){
            segs[rt].cover++;
            return ;
        }
        if(id <= mid){
            Update(lson,id);
        }else{
            Update(rson,id);
        }
        PushUp(rt);
    }
    int query(int rt,int L, int R,int k){
        if(L == R){
            return L;
        }
        if(k <= segs[rt*2].cover){
            return query(lson,k);
        }else{
            return query(rson,k-segs[rt*2].cover);
        }
    }
    int main(){
        int n, k, m;
        while(scanf("%d%d%d",&n,&k,&m)!=EOF){
            buildtree(1,1,n);
            LL a;
            for(int i = 1; i <= n; i++){
                scanf("%lld",&a);
                presum[i] = presum[i-1] + a;
            }
            int l, r;
            for(int i = 1; i <= m; i++){
                scanf("%d%d",&l,&r);
                intervals[i].l = l;
                intervals[i].r = r;
            }
            sort(intervals+1,intervals+1+m,cmp);
            for(int i = m-k+1; i <= m; i++){
                Update(1,1,n,intervals[i].l);
            }
            LL ans = 0;
            for(int i = m-k+1; i >= 1; i--){
                int l = query(1,1,n,k);
                if(l <= intervals[i].r){
                    ans = max(ans, presum[intervals[i].r] - presum[l-1]);
                }
                Update(1,1,n,intervals[i-1].l);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    /*
    5 1 1
    1 2 3 4 6
    4 5
    
    3 4
    
    
    */
    

      

     
  • 相关阅读:
    Class:向传统类模式转变的构造函数
    连载:面向对象葵花宝典:思想、技巧与实践(34)
    Java Web文件下载
    POJ 1469(裸二分匹配)
    查看程序占用tomcat内存情况
    《对象程序设计》课程 课程设计、考试安排 及 教师建议(2014.06.30修正)
    zoj 1880
    STM8S PWM 应用 呼吸灯
    Android开发系列(二十四):Notification的功能与使用方法
    HDU 4499 Cannon (暴力搜索)
  • 原文地址:https://www.cnblogs.com/chengsheng/p/5533386.html
Copyright © 2011-2022 走看看