E. Linear Kingdom Races

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;
}
相关推荐
寂静山林4 分钟前
UVa 10228 A Star not a Tree?
算法
Neverfadeaway16 分钟前
【C语言】深入理解函数指针数组应用(4)
c语言·开发语言·算法·回调函数·转移表·c语言实现计算器
Madison-No71 小时前
【C++】探秘vector的底层实现
java·c++·算法
Swift社区1 小时前
LeetCode 401 - 二进制手表
算法·leetcode·ssh
派大星爱吃猫1 小时前
顺序表算法题(LeetCode)
算法·leetcode·职场和发展
liu****1 小时前
8.list的模拟实现
linux·数据结构·c++·算法·list
地平线开发者2 小时前
征程 6 | 征程 6 工具链如何支持 Matmul/Conv 双 int16 输入量化?
算法·自动驾驶
程序员大雄学编程3 小时前
「深度学习笔记4」深度学习优化算法完全指南:从梯度下降到Adam的实战详解
笔记·深度学习·算法·机器学习
小O的算法实验室4 小时前
2022年ASOC SCI2区TOP,基于竞争与合作策略的金字塔粒子群算法PPSO,深度解析+性能实测,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
武帝为此4 小时前
【B树与B+树详解】
数据结构·b树