E. Linear Kingdom Races

来源:互联网 发布:ubuntu 移除ppa 编辑:程序博客网 时间:2024/06/05 14:56

http://codeforces.com/problemset/problem/115/E


//dp[i]表示 [i...i]最多能赚多少钱//dp[i+1]=max(dp[i],dp[k]-sum(cost[k..i])+sum(profit[k...i]))  1<=k<i;//两个转移分别是1.不修路,2.把修[k...i]能赚得钱//线段树优化#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>using namespace std;#define LL(x) (x<<1)#define RR(x) ((x<<1)|1)typedef __int64 lld;const int maxn=200005;int cost[maxn];struct Seg{int l,r;lld flag;lld max;}tree[maxn*4];void build(int l,int r,int k){tree[k].l=l;tree[k].r=r;tree[k].max=0;tree[k].flag=0;if(l==r) return ;int mid=(l+r)>>1;build(l,mid,LL(k));build(mid+1,r,RR(k));}lld Max(lld a,lld b){if(a<b)return b;return a;}void push_down(int k){if(tree[k].flag){tree[RR(k)].max+=tree[k].flag;tree[LL(k)].max+=tree[k].flag;tree[RR(k)].flag+=tree[k].flag;tree[LL(k)].flag+=tree[k].flag;tree[k].flag=0;}}void push_up(int k){tree[k].max=Max(tree[LL(k)].max,tree[RR(k)].max);}void update(int l,int r,int k,lld v){if(l<=tree[k].l && tree[k].r<=r){tree[k].flag+=v;tree[k].max+=v;return;}push_down(k);int mid=(tree[k].l+tree[k].r)>>1;if(l<=mid) update(l,r,LL(k),v);if(r> mid) update(l,r,RR(k),v);push_up(k);}struct node {int x,y;lld p;bool operator < (const node &t ) const {return y<t.y;}}r[maxn];lld dp[maxn];int main(){int n,m;int i,j,k;while(scanf("%d%d",&n,&m)!=EOF){for(i=1;i<=n;i++)scanf("%d",&cost[i]);for(i=0;i<m;i++)scanf("%d%d%I64d",&r[i].x,&r[i].y,&r[i].p);sort(r,r+m);memset(dp,0,sizeof(dp));build(0,n,1);for(i=1,j=0;i<=n;i++){update(0,i-1,1,-cost[i]);while(j<m && r[j].y<=i){update(0,r[j].x-1,1,r[j].p);j++;}dp[i]=Max(dp[i-1],tree[1].max);update(i,i,1,dp[i]);}printf("%I64d\n",dp[n]);}return 0;}