https://codeforces.com/problemset/problem/115/E
线段树优化dp O(n2)->O(nlogn)
分析题意发现可以有暴力dp
dp(i)是前i条路最大利润
dp(i)=dp(i-1)不选第i条路
dp(i)=max(dp(j)+val(j)-cost(j))选这i条路
dp(i)=max(dp(i-1),max(dp(j)+val(j)-cost(j))
显然右边值可以用线段树优化,不需要枚举
思考枚举就是val(j)-cost(j)+dp(j) 因此我们可以直接维护这些值
枚举i
(0-i-1)减去(a(i))建立这条路需要的钱
枚举建立前i条路可以获利的
(0-l-1)加上
求区间max(0,i-1) 从(i-1)内转移到 i
给i赋值dp(i)
ans=dp(n)
cpp
// Problem: E. Linear Kingdom Races
// Contest: Codeforces - Codeforces Beta Round 87 (Div. 1 Only)
// URL: https://codeforces.com/contest/115/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<vector>
#include<algorithm>
#define INF 1e6
using namespace std;
const int N=2e5+9;
typedef long long ll;
int a[N];
ll dp[N];
struct competition{
int l;
ll w;
};
vector<competition> race[N];
struct SEG{
struct node{
ll mx;
ll tag;
}seg[N<<2];
#define tl(id) id<<1
#define tr(id) id<<1|1
#define pushup(id) seg[id].mx=max(seg[tl(id)].mx,seg[tr(id)].mx)
int inrange(int L,int R,int l,int r){return L>=l && R<=r;}
int outofrange(int L,int R,int l,int r){return L>r || l>R;}
void maketag(int id,ll v){
seg[id].mx+=v;
seg[id].tag+=v;
}
void pushdown(int id){
maketag(tl(id),seg[id].tag);
maketag(tr(id),seg[id].tag);
seg[id].tag=0;
}
void modify(int id,int L,int R,int l,int r,ll v){
if(inrange(L,R,l,r)){
maketag(id,v);
}else if(!outofrange(L,R,l,r)){
int mid=(L+R)>>1;
pushdown(id);
modify(tl(id),L,mid,l,r,v);
modify(tr(id),mid+1,R,l,r,v);
pushup(id);
}
}
ll query(int id,int L,int R,int l,int r){
if(inrange(L,R,l,r)){
return seg[id].mx;
}else if(!outofrange(L,R,l,r)){
int mid=(L+R)>>1;
return max(query(tl(id),L,mid,l,r),query(tr(id),mid+1,R,l,r));
}else{
return 0;
}
}
}t;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
int l,r,w;
cin>>l>>r>>w;
race[r].push_back((competition){l,w});
}
for(int i=1;i<=n;i++){
t.modify(1,0,n,0,i-1,-a[i]);
for(int j=0;j<race[i].size();j++){
competition tt =race[i][j];
t.modify(1,0,n,0,tt.l-1,tt.w);
}
dp[i]=max(dp[i-1],t.query(1,0,n,0,i-1));
t.modify(1,0,n,i,i,dp[i]);
}
cout<<dp[n]<<'\n';
return 0;
}