【题解】 CF115E:Linear Kingdom Races

Linear Kingdom Races

如果考虑每个比赛是否进行,有些比赛会有道路会重叠,代价会重复计算,所以设状态为 \(f_i\) 为在前 \(i\) 个道路中选了若干个道路获得最大利润。

选择不修这个道路,那直接转移 \(f_i=f_{i-1}\)

选择修这个道路,选择一个枚举点 \(j\)\(f_i=max\{{ f_j+val(j+1,i)-cost(j+1,i)}\}\)\(val(j+1,i)\)表示区间 \([j+1,i]\) 所有比赛的总获利,\(cost(j+1,i)\) 表示修区间 \([j+1,i]\) 全部的道路所用的代价。

发现求最大值可以用线段树维护 \(t[x]\) 使得选出最大的值转移。

对于新的i:

\([0,i-1]\)\(t[x]\) 都减去 \(a_i\) 因为都需要修这条道路。

对于当前 \(r=i\) 的比赛(\(l,r,w\)),\([0,l-1]\)\(t[x]\) 都会获得该利润,都加上 \(w\)

\([0,i-1]\)\(t[x]\) 最大值转移到 \(t[i]\)

我觉得这就是所谓的被动转移吧,我们主动选择比赛进行转移就是所谓的主动转移,我们维护最大值转移就是所谓的被动转移。

#include <bits/stdc++.h>
#define ll long long
#define int ll
#define ls p<<1
#define rs p<<1|1
#define re register
#define pb push_back
#define pir pair<int,int>
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lb(x) x&(-x);
using namespace std;
const int N=1e6+10;
const int B=1e6+5;
const int M=8e6+10;
const int mod=1e9+7;
int n,m;
int a[N];
int f[N];
vector<pir> v[N];
int t[N];
int maxn[N<<2];
int tag[N<<2];
void pushdown(int p){
if(!tag[p]) return;
maxn[ls]+=tag[p];
maxn[rs]+=tag[p];
tag[ls]+=tag[p];
tag[rs]+=tag[p];
tag[p]=0;
}
void change(int p,int pl,int pr,int l,int r,int w){
if(l<=pl&&pr<=r){
maxn[p]+=w;
tag[p]+=w;
return;
}
pushdown(p);
int mid=(pl+pr)>>1;
if(l<=mid) change(ls,pl,mid,l,r,w);
if(r>mid) change(rs,mid+1,pr,l,r,w);
maxn[p]=max(maxn[ls],maxn[rs]);
return;
}
int query(int p,int pl,int pr,int l,int r){
if(l<=pl&&pr<=r){
return maxn[p];
}
pushdown(p);
int mid=(pl+pr)>>1;
int res=-1e9;
if(l<=mid) res=max(res,query(ls,pl,mid,l,r));
if(r>mid) res=max(res,query(rs,mid+1,pr,l,r));
return res;
}
void solve(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
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;
v[r].push_back({l,w});
}
for(int i=1;i<=n;i++){
change(1,0,n,0,i-1,-a[i]);
for(auto j:v[i]){
change(1,0,n,0,j.first-1,j.second);
}
f[i]=max(f[i-1],query(1,0,n,0,i-1));
change(1,0,n,i,i,f[i]);
}
cout<<f[n]<<"\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(nullptr);
int t=1;
// cin>>t;
while(t--){
solve();
}
return 0;
}
posted @   sad_lin  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示