Description

Sean准备投资一些项目。有n个投资项目,投资第i个项目需要花费Ci元。Sean发现如果投资了某些编号连续的项目就能赚得一定的钱。现在给出m组连续的项目和每组能赚得的钱,请问采取最优的投资策略的最大获利是多少?

样例最佳策略是全部项目都投资,然后第1,2组都满足了,获利为2+2-3=1。最佳策略可能是不投资,即最大获利为0。

Input

每组数据第一行输入两个整数N和M , N表示项目数,M表示能获利的连续的项目组数,1 <= N <= 20000,1 <= M <= 20000 , 接下来一行输入N个数,表示每个项目投资需要的花费Ci,1<=Ci<=10^9。

接下来m行,每行3个数Li,Ri,Pi,1<=Li<=Ri<=N,1<=Pi<=10^9,表示投资从第Li到第Ri这些连续的项目的获利。每组连续投资的获利互不影响,如果投资的多组连续投资都包含项目i,项目i只需要投资一次。

Output

对于每组数据输出一行,即最大获利。

Sample Input

3 2
1 1 1
1 2 2
2 3 2

Sample Output

1
 
 
 
 
设dp[i]表示,前i个项目的最大获利。
转移方程 : dp[i] = max( dp[i-1] , dp[j-1] + w[j][i] ) , ( 1<=j <=n ).
枚举状态费用O(n) , 用线段树优化取最值,更新费用为O(log n ) , 总复杂度为O(n log n )。
线段树的每个节点i表示 ,  从i连续投资到当前节点的最大利润
 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <algorithm>
using namespace std; typedef long long LL;
const int N = ;
const int inf = 1e9+;
const double PI = acos(-1.0);
const double eps = 1e- ; #define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define lr rt<<1
#define rr rt<<1|1 int n , m ;
struct node {
int l , r , w ;
bool operator < ( const node &a ) const {
if( r != a.r ) return r < a.r ;
else return l > a.l ;
}
}e[N]; LL dp[N] , cost[N] ; void init(){
memset( dp , , sizeof dp );
} LL date[N<<] ,lazy[N<<]; void build( int l , int r , int rt ) {
date[rt] = lazy[rt] = ;
if( l == r ) return ;
int mid = ( l + r ) >> ;
build(lson); build(rson);
} void Down( int l , int r , int rt ) {
if( l == r ) return ;
if( lazy[rt] != ) {
date[lr]+= lazy[rt] , lazy[lr] += lazy[rt];
date[rr]+= lazy[rt] , lazy[rr] += lazy[rt];
lazy[rt] = ;
}
} void Up( int rt ) { date[rt] = max( date[lr] , date[rr] ); } void update( int l , int r , int rt , int L , int R , LL val) { if( L == l && r == R ) {
date[rt] += val , lazy[rt] += val ; return ;
}
Down(l,r,rt);
int mid = (l+r) >> ;
if( R <= mid ) update(lson,L,R,val);
else if( L > mid ) update(rson,L,R,val);
else update(lson,L,mid,val) , update(rson,mid+,R,val);
Up(rt);
} LL query( int l , int r , int rt , int L , int R ) { if( L == l && r == R ) {
return date[rt];
}
Down(l,r,rt);
int mid = (l+r)>>;
if( R <= mid ) return query(lson,L,R);
else if( L > mid ) return query(rson,L,R);
else return max( query(lson,L,mid),query(rson,mid+,R) );
} void run () {
init() ;
build(root);
for( int i = ; i <= n ; ++i ){
scanf("%I64d",&cost[i]) ;
}
for( int i = ; i < m ; ++i ) {
scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);
}
sort( e , e + m );
int head = ;
for( int i = ; i <= n ; ++i ) {
update( root , i , i , dp[i-] );
update( root , , i , -cost[i] );
while( head < m && e[head].r <= i )
update( root , , e[head].l , e[head].w ) , head++ ;
dp[i] = max( dp[i-] , query( root , , i ) );
}
printf("%I64d\n",dp[n]);
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
ios::sync_with_stdio(false);
while( ~scanf("%d%d",&n,&m) )run() ;
}
 

FZU 2079 最大获利(线段树+DP)的更多相关文章

  1. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  2. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  3. FZu Problem 2236 第十四个目标 (线段树 + dp)

    题目链接: FZu  Problem 2236 第十四个目标 题目描述: 给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续 解题思路: 又遇到了用线段树来优化dp的题目,线段树节点里 ...

  4. lightoj1085 线段树+dp

    //Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...

  5. [CF 474E] Pillars (线段树+dp)

    题目链接:http://codeforces.com/contest/474/problem/F 意思是给你两个数n和d,下面给你n座山的高度. 一个人任意选择一座山作为起始点,向右跳,但是只能跳到高 ...

  6. HDU-3872 Dragon Ball 线段树+DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872 题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段, ...

  7. HDU4521+线段树+dp

    题意:在一个序列中找出最长的某个序列.找出的序列满足题中的条件. 关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小.可以利用线段树进行统计,查询.更新的时候利用dp的思想. / ...

  8. Codeforces Round #343 (Div. 2) D - Babaei and Birthday Cake 线段树+DP

    题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...

  9. Special Subsequence(离散化线段树+dp)

    Special Subsequence Time Limit: 5 Seconds      Memory Limit: 32768 KB There a sequence S with n inte ...

随机推荐

  1. Windows平台下在Emacs中使用plantuml中文乱码问题(已解决)

    Windows平台下在Emacs中使用plantuml中文乱码问题(已解决) */--> code {color: #FF0000} pre.src {background-color: #00 ...

  2. Codeforces 492B Name That Tune ( 期望DP )

    B. Name That Tune time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  3. 解决MVC中textarea出现多余空格的问题

    public static MvcHtmlString FixedTextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> ...

  4. Using-JSONNET-for-dynamic-JSON-parsing

    原文 https://weblog.west-wind.com/posts/2012/Aug/30/Using-JSONNET-for-dynamic-JSON-parsing With the re ...

  5. SQL的子查询与JOIN的小试牛刀

    //学生表CREATE TABLE student( ID INT PRIMARY KEY, s_name ) NOT NULL, class_id INT NOT NULL); , "qf ...

  6. matlab 代码分析

    在command window中输入 >> profile on>> profile clear>> profile viewer 就会出现如下窗口 在将头所指向的 ...

  7. 记一次引入less自己坑自己的坑....

    loader里该有的loader都有了,但是在npm run dev的时候,就是找不到less文件. 最后,才发现,用了postcss-loader,但是去package.json里查了一下,并没有安 ...

  8. Django--分页器(paginator)、Django的用户认证、Django的FORM表单

    分页器(paginator) >>> from django.core.paginator import Paginator >>> objects = ['joh ...

  9. Python--反射(重点)、面向对象内置方法:如__str__、面向对象的软件开发

    复习: Python3统一了类与类型 类的名称空间在定义阶段产生,看名称空间:类.__dict__ Python3特点:可以多继承 Python3都是新式类 继承意义:解决重复代码   组合:也是解决 ...

  10. The Second Scrum Meeting!

    第七周会议 情况简述 会议概要:汇报已完成的任务,讨论并解决遇到的问题 参与人员:詹晓宇  谢赛金  熊紫仁  徐翠萍  周娟  孙尚煜 会议地点:六区研讨性教室 具体内容 小组成员 已完成任务 计划 ...