区间交

原创 2016年06月01日 23:17:23

区间交

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



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
 

题解:

         题目要求从m个区间中找出k个区间的交区间,且交区间的sum(a[l],a[r])的和最大. 我们可以考虑转换这个问题.变为求原序列的一段区间被多少个区间覆盖.

         假设当前找的是区间[L,R],那么很显然某个区间要包含这个[L,R],它的左右端点必须要L,R的两边. 知道这个,我们只需要处理那些左端点<=L的.然后再通过树状

         数组求出有多少个右端点>=R.然后对于原序列的区间,只需要尺取一下就行了.


AC代码:

#include <iostream>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[N],c[N];

struct Interval
{
    int l,r;
    void read()
    {
        scanf("%d %d",&l,&r);
    }
    bool operator < (const Interval &a) const
    {
        return l < a.l;
    }
} interval[N];

void add(int x,int n)
{
    while(x <= n)
    {
        c[x]++;
        x += x & -x;
    }
}

int get(int x)
{
    int s = 0;
    x--;
    while(x > 0)
    {
        s += c[x];
        x -= x & -x;
    }
    return s;
}

void solve()
{
    int n,k,m;
    while(~scanf("%d %d %d",&n,&k,&m))
    {
        memset(c,0,sizeof c);
        for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
        for(int i = 1; i <= m; ++i) interval[i].read();
        sort(interval + 1,interval + m + 1);
        ll ans = 0,sum = 0;
        int l,pos;
        pos = l = 1;
        for(int r = 1; r <= n; ++r)
        {
            sum += a[r];
            while(l <= r)
            {
                while(pos <= m && interval[pos].l <= l)
                    add(interval[pos++].r,n);
                int num = pos - 1 - get(r);
                if(num >= k)
                {
                    ans = max(ans,sum);
                    break;
                }
                else
                {
                    sum -= a[l];
                    l++;
                }
            }
        }
        cout << ans << endl;
    }
}

int main()
{
    solve();
    return 0;
}


版权声明:追逐心中的梦想,永不放弃! By-xdlove

相关文章推荐

【51Nod】1672 - 区间交(线段树 & 贪心)

点击打开题目 1672 区间交 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  取消关注 ...
  • wyg1997
  • wyg1997
  • 2016年08月13日 09:59
  • 393

NYOJ14 会场安排问题 (选择不想交区间)

会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是...

【BZOJ3379】【USACO2004】交作业 区间DP

题目描述  数轴上有nn个点,你要从位置00去位置BB,你每秒钟可以移动11单位。还有mm个限制,每个限制(x,y)(x,y)表示你要在第tt秒之后(可以是第tt秒)经过位置yy。问你最少需要几秒。 ...
  • ez_yww
  • ez_yww
  • 2017年11月06日 16:45
  • 26

ZOJ 3961 Let's Chat (双指针 + 区间交)

ACM (ACMers’ Chatting Messenger) is a famous instant messaging software developed by Marjar Technolo...

【HDU5700 区间交】

题目链接:区间交 Sample Input 5 2 3 1 2 3 4 6 4 5 2 5 1 4Sample Output 10题意 有n个区间,求k个区间,使得这k个区间相交的区间...

[hdu 5700 区间交]树状数组+二分

[hdu 5700 区间交]树状数组+二分知识点:data structure binary index tree1. 题目链接[hdu 5700 区间交] 类似题目:[Codeforces 754...

Codeforces Problem 714A Meeting of Old Friends(区间交)

Codeforces Problem 714A Meeting of Old Friends(区间交)

线段树 hdu5700 区间交

传送门:点击打开链接 题意:有n个区间,求k个区间,使得这k个区间相交的区间内数字之和最大。数列的数字均>=0 思路:通常这种题目我们都会先按照区间的右区间位置排序。之后的步骤如果想到了,就会变得...

51 nod 区间交 (优先队列)

1672 区间交 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 小A有一个含有n个非负整数的数...

hdu5700 区间交 思维

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5700 题目大意:  Problem Description 小A有一个含有n个非负整数的数列与...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:区间交
举报原因:
原因补充:

(最多只允许输入30个字)