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): 849    Accepted Submission(s): 377


    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
    /*
    hdu 5700区间交(线段树)
    
    problem:
    给你一串数字以及m个区间,然后选择其中的k个区间使区间相交区域的和最大
    
    solve:
    最开始想的是二分答案然后判断能否找出k个区间使其的和达到,但是推着推着发现和以前的做过的线段树处理区间问题很像
    枚举区间的右端点,然后找出左边哪个端点使其刚好覆盖的k个区间,然后求值取最大值
    所以需要维护左端的个数,以及查找出第k小的左端点,用线段树解决.
    因为枚举的是以当前点为最终区间的右端点,所以出现过的区间要除去(即删除它的左端点).
    
    hhh-2016-08-13 15:15:56
    */
    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <functional>
    #include <map>
    #include <set>
    using namespace std;
    #define lson  (i<<1)
    #define rson  ((i<<1)|1)
    typedef long long ll;
    typedef unsigned int ul;
    const int INF = 0x3f3f3f3f;
    const int  maxn = 100000+10;
    const int mod = 1e9+7;
    
    struct Tree
    {
        int l,r;
        int lval,mid;
    } tree[maxn<<2];
    
    void push_up(int i)
    {
        tree[i].lval = tree[lson].lval+tree[rson].lval;
    }
    
    void build(int i,int l,int r)
    {
        tree[i].l = l,tree[i].r = r,tree[i].lval = 0;
        if(l == r)
            return;
        tree[i].mid= (l+r) >>1;
        int mid = tree[i].mid;
        build(lson,l,mid);
        build(rson,mid+1,r);
        push_up(i);
    }
    
    void Insert(int i,int k,int val)
    {
        if(tree[i].l == tree[i].r && tree[i].l == k)
        {
            tree[i].lval += val;
    //        cout <<"pos: " << tree[i].l <<" val: "<<tree[i].lval<< endl;
            return ;
        }
    //    cout <<tree[i].l << " "<< tree[i].r << "k "<<k <<" val: "<<val<< endl;
        int mid = tree[i].mid;
    
        if(k <= mid)
            Insert(lson,k,val);
        else
            Insert(rson,k,val);
        push_up(i);
    //    cout <<tree[i].l << " "<< tree[i].r <<" val: "<<tree[i].lval<< endl;
    }
    
    int query(int i ,int k)
    {
    //    cout << tree[i].lval << " " <<tree[i].l << " "<< tree[i].r <<endl;
        if(tree[i].l == tree[i].r)
            return tree[i].l;
        if(k <= tree[lson].lval)
            return query(lson,k);
        else
           return  query(rson,k-tree[lson].lval);
        push_up(i);
    }
    
    int query_num(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            return tree[i].lval;
        }
        int num = 0;
        if(l <= tree[i].mid)
            num += query_num(lson,l,r);
        if(r > tree[i].mid)
            num += query_num(rson,l,r);
        return num;
    }
    
    struct node
    {
        int l,r;
    } pnode[maxn];
    
    ll Max(ll a,ll b)
    {
        if(a < b)
            return b;
        return a;
    }
    
    bool cmp(node a,node b)
    {
        if(a.r != b.r)
            return a.r < b.r;
        else
            return a.l < b.l;
    }
    ll num[maxn];
    int main()
    {
        int n,k,m;
        while(scanf("%d%d%d",&n,&k,&m) != EOF)
        {
            num[0] = 0;
            build(1,1,n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%I64d",&num[i]);
                num[i] += num[i-1];
            }
            for(int i = 1; i <= m; i++)
            {
                scanf("%d%d",&pnode[i].l,&pnode[i].r);
                Insert(1,pnode[i].l,1);
            }
            sort(pnode+1,pnode+m+1,cmp);
    
            int now = 1;
            ll ans = 0;
            for(int i = 1; i <= n && now <= m; i++)
            {
                if(i == pnode[now].r)
                {
    //                cout << "r:"<<pnode[now].r << endl;
                    int t = query_num(1,1,i);
                    if(t >= k)
                    {
                        int l = query(1,k);
    //                     cout<<"l:" << l << endl;
                        ans = Max(ans,num[i]-num[l-1]);
                    }
    //                cout<<"ans:"<<ans <<"  t:" << t << endl;
                }
                while(now <= m && pnode[now].r == i)
                {
                    Insert(1,pnode[now].l,-1);
                    now ++;
                }
            }
            cout << ans <<endl;
        }
        return 0;
    }
    
    /*
    5 2 3
    1 2 3 4 5
    1 2
    3 4
    5 5
    */
    

      

  • 相关阅读:
    [git] git 的基本认知
    [Java] Java IO Files
    [Java] Java IO 概况
    [Java] JavaMail 发送带图片的 html 格式的邮件
    [Java] HashMap 导致的高 CPU 使用率
    [Struts] Hello World Demo
    [Hibernate] 注解映射例子
    [Hibernate] List 映射例子
    cmd的xcopy命令
    wpf custom control
  • 原文地址:https://www.cnblogs.com/Przz/p/5792145.html
Copyright © 2011-2022 走看看