区间交

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(1≤n≤100000,1≤k≤m≤100000)。

接下来一行n个数ai,表示lyk的数列(0≤ai≤109)。

接下来m行,每行两个数li,ri,表示每个区间(1≤li≤ri≤n)。

 
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
*/

  

hdu 5700区间交(线段树)的更多相关文章

  1. HDU 5700 区间交 线段树暴力

    枚举左端点,然后在线段树内,更新所有左边界小于当前点的区间的右端点,然后查线段树二分查第k大就好 #include <cstdio> #include <cstring> #i ...

  2. HDU 5700 区间交 离线线段树

    区间交 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5700 Description 小A有一个含有n个非负整数的数列与m个区间.每个区间可以表示为 ...

  3. HDU 5700 区间交(线段树)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5700 [题目大意] 给出一个长度为n的数列和m个区间,现在求k个区间,使得他们的区间交内的数列项和 ...

  4. HDU 5700——区间交——————【线段树+枚举】

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  5. HDU 5700 区间交

    枚举起点 二分终点 树状数组check #include<iostream> #include<cstring> #include<cmath> #include& ...

  6. HDU 1540 区间合并线段树

    题目大意: 就是给定一堆位置,进行删除还原,最后找到 t 位置上的最大连续位置 #include <cstdio> #include <cstring> #include &l ...

  7. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  8. 【BZOJ4653】【NOI2016】区间(线段树)

    [BZOJ4653][NOI2016]区间(线段树) 题面 BZOJ 题解 \(NOI\)良心送分题?? 既然是最大长度减去最小长度 莫名想到那道反复减边求最小生成树 从而求出最小的比值 所以这题的套 ...

  9. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

随机推荐

  1. 使用Python定制词云

    一.实验介绍 1.1 实验内容 在互联网时代,人们获取信息的途径多种多样,大量的信息涌入到人们的视线中.如何从浩如烟海的信息中提炼出关键信息,滤除垃圾信息,一直是现代人关注的问题.在这个信息爆炸的时代 ...

  2. 400多个开源项目以及43个优秀的Swift开源项目-Swift编程语言资料大合集

    Swift 基于C和Objective-C,是供iOS和OS X应用编程的全新语言,更加高效.现代.安全,可以提升应用性能,同时降低开发难度. Swift仍然处于beta测试的阶段,会在iOS 8发布 ...

  3. Linux 帳號管理與 ACL 權限設定

    1. Linux 的账号与群组1.1 使用者识别: UID 与 GID1.2 使用者账号:/etc/passwd, /etc/shadow1.3 关于群组: 有效与初始群组. groups, newg ...

  4. css变化代码

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  5. .net 小程序获取用户UnionID

    第一次写博客,写的不好多多海涵! 1.小程序获取UnionID的流程用code去换取session_key,然后去解密小程序获取到的那串字符! 话不多说,原理大家都懂!!!!!! 直接上代码 publ ...

  6. ASCII排序

    ASCII码排序 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符.   输入 第一行输 ...

  7. JQuery 动态加载iframe.

    html: <iframe id="ifm" style="width:inherit;height:inherit" runat="serve ...

  8. openssl几个加密算法使用介绍

    1.openssl简介 1)openssl概述 OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. ...

  9. C#制作ActiveX插件

    首先新建项目--->类库,取名:ActiveXDemo 右键项目属性:应用属性==>程序集信息=>使程序集Com可见, 生成==>输出==>为com互操作注册 新建接口类 ...

  10. HTML mate标签

    META标签分两大部分:HTTP标题信息(http-equiv)和页面描述信息(name). http-equiv http-equiv类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正 ...