题目

给定一个大小为 \(n\) 的序列,要求支持单点修改和查询区间内至多 \(k\) 个不交子区间之和的最大值(可以不取)


分析

考虑源点向每个点、每个点向汇点流流量1费用0的边,每个点向右边的点流流量1费用\(a_i\)的边,流量最大为 \(k\),这样构建出一个费用流的模型。

很显然,退流相当于给区间取反,而可以利用反悔贪心,在线段树上维护最大子段和和最小子段和,在最大子段和大于0的情况下取反至多 \(k\) 次区间,查询完再恢复原状

复杂度 \(O(nk\log n)\)


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <stack>
using namespace std;
const int N=100011; int n,a[N];
stack<pair<int,int> >st;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(int ans){
if (ans<0) putchar('-'),ans=-ans;
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Rec{int l,r,z;};
struct rec{
Rec wmax,wmin,lmax,lmin,rmax,rmin; int sum,lazy;
void ptag(int x,int y){
wmax=wmin=lmax=lmin=rmax=rmin=(Rec){x,x,y};
sum=y,lazy=0;
}
void rev(){
swap(wmax,wmin),swap(lmax,lmin),swap(rmax,rmin);
wmax.z=-wmax.z,wmin.z=-wmin.z,
lmax.z=-lmax.z,lmin.z=-lmin.z,
rmax.z=-rmax.z,rmin.z=-rmin.z;
sum=-sum,lazy^=1;
}
}w[N<<2];
rec pup(rec f,rec g){
rec h; h.lazy=0;
h.sum=f.sum+g.sum;
if (f.lmax.z<f.sum+g.lmax.z) h.lmax=(Rec){f.lmax.l,g.lmax.r,f.sum+g.lmax.z};
else h.lmax=f.lmax;
if (f.lmin.z>f.sum+g.lmin.z) h.lmin=(Rec){f.lmin.l,g.lmin.r,f.sum+g.lmin.z};
else h.lmin=f.lmin;
if (g.rmax.z<f.rmax.z+g.sum) h.rmax=(Rec){f.rmax.l,g.rmax.r,f.rmax.z+g.sum};
else h.rmax=g.rmax;
if (g.rmin.z>f.rmin.z+g.sum) h.rmin=(Rec){f.rmin.l,g.rmin.r,f.rmin.z+g.sum};
else h.rmin=g.rmin;
h.wmax=f.wmax.z>g.wmax.z?f.wmax:g.wmax;
if (h.wmax.z<f.rmax.z+g.lmax.z) h.wmax=(Rec){f.rmax.l,g.lmax.r,f.rmax.z+g.lmax.z};
h.wmin=f.wmin.z<g.wmin.z?f.wmin:g.wmin;
if (h.wmin.z>f.rmin.z+g.lmin.z) h.wmin=(Rec){f.rmin.l,g.lmin.r,f.rmin.z+g.lmin.z};
return h;
}
void build(int k,int l,int r){
if (l==r){
w[k].ptag(l,a[l]);
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
w[k]=pup(w[k<<1],w[k<<1|1]);
}
void update(int k,int l,int r,int x,int y){
if (l==r){
w[k].ptag(x,y);
return;
}
int mid=(l+r)>>1;
if (w[k].lazy){
w[k<<1].rev(),w[k<<1|1].rev();
w[k].lazy=0;
}
if (x<=mid) update(k<<1,l,mid,x,y);
else update(k<<1|1,mid+1,r,x,y);
w[k]=pup(w[k<<1],w[k<<1|1]);
}
void flip(int k,int l,int r,int x,int y){
if (l==x&&r==y){
w[k].rev();
return;
}
int mid=(l+r)>>1;
if (w[k].lazy){
w[k<<1].rev(),w[k<<1|1].rev();
w[k].lazy=0;
}
if (y<=mid) flip(k<<1,l,mid,x,y);
else if (x>mid) flip(k<<1|1,mid+1,r,x,y);
else flip(k<<1,l,mid,x,mid),flip(k<<1|1,mid+1,r,mid+1,y);
w[k]=pup(w[k<<1],w[k<<1|1]);
}
rec query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k];
int mid=(l+r)>>1;
if (w[k].lazy){
w[k<<1].rev(),w[k<<1|1].rev();
w[k].lazy=0;
}
if (y<=mid) return query(k<<1,l,mid,x,y);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
else return pup(query(k<<1,l,mid,x,mid),query(k<<1|1,mid+1,r,mid+1,y));
}
int main(){
n=iut();
for (int i=1;i<=n;++i) a[i]=iut();
build(1,1,n);
for (int Q=iut();Q;--Q)
if (iut()){
int l=iut(),r=iut(),k=iut(),ans=0;
while (k--){
rec t=query(1,1,n,l,r);
if (t.wmax.z<=0) break;
ans+=t.wmax.z;
flip(1,1,n,t.wmax.l,t.wmax.r);
st.push(make_pair(t.wmax.l,t.wmax.r));
}
print(ans),putchar(10);
while (!st.empty()) flip(1,1,n,st.top().first,st.top().second),st.pop();
}else{
int x=iut(),y=iut();
update(1,1,n,x,y);
}
return 0;
}

#线段树,模拟费用流#CF280D k-Maximum Subsequence Sum的更多相关文章

  1. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流

    昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...

  2. [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)

    https://www.cnblogs.com/DaD3zZ-Beyonder/p/5634149.html k可重区间集问题有两种建图方式,可能这一种才可以被线段树优化. 换个角度看,这也是一个类似 ...

  3. 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并

    题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...

  4. Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]

    洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...

  5. 【BZOJ3638】Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)

    [BZOJ3638]Cf172 k-Maximum Subsequence Sum Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交 ...

  6. BZOJ 5326 [JSOI2017]博弈 (模拟费用流、线段树)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5326 题解 终于成为第8个A掉这题的人--orz tzw神仙早我6小时 本以为这东西常数 ...

  7. BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...

  8. BZOJ 1920 Luogu P4217 [CTSC2010]产品销售 (模拟费用流、线段树)

    题目链接 (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=1920 (luogu) https://www.luogu.org/prob ...

  9. 【网络流24题】最长k可重线段集(费用流)

    [网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...

  10. 模拟费用流 & 可撤销贪心

    1. CF730I Olympiad in Programming and Sports 大意: $n$个人, 第$i$个人编程能力$a_i$, 运动能力$b_i$, 要选出$p$个组成编程队, $s ...

随机推荐

  1. 项目实战:Qt+OSG教育学科工具之地理三维星球

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  2. 【Azure 应用服务】VS2019发布应用到正在运行的App Service时失败问题的解决

    问题描述 在VS 2019中配置号App Service的Publish Profile后,发布应用出现错误.根据VS 2019中的输出消息可知有文件正在运行中,无法被替换,所以发布失败. 问题解决 ...

  3. 【Azure Redis 缓存】使用Azure Redis服务时候,如突然遇见异常,遇见命令Timeout performing SET xxxxxx等情况,如何第一时间查看是否有Failover存在呢?

    问题描述 使用Azure Redis服务时,如突然遇见异常,命令Timeout performing SET xxxxxx等情况,如何第一时间查看是否有Failover存在呢?看是否有进行平台的维护呢 ...

  4. 详解SSL证书系列(4)免费的SSL证书和收费的证书有什么区别

    上一篇介绍了如何选择SSL证书,更多地是从证书类型角度介绍的.SSL证书有免费和收费的,那么它们之间有什么区别呢? SSL证书免费和收费的主要区别体现在以下几个方面: 1,验证类型 免费SSL证书通常 ...

  5. Spark任务性能调优总结

    一.shuffle调优 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘IO.序列化.网络数据传输等操作.因此,如果要让作业的性能更上一层楼,就有必要对shuf ...

  6. Jmeter 响应断言你知道多少?

    1 断言各组件介绍 Apply to:同上 测试字段: * 响应文本:响应体 * 响应代码:响应状态码 * 响应信息:状态码的消息 * 响应头:顾名思义就是响应头 * 请求头:顾名思义就是请求头 * ...

  7. 用几张图实战讲解MySQL主从复制

    本文分享自华为云社区<结合实战,我为MySQL主从复制总结了几张图!>,作者: 冰 河. MySQL官方文档 MySQL 主从复制官方文档链接地址如下所示: http://dev.mysq ...

  8. CPN Tools 系统建模分析工具(持续更新)

    一直想把之前看有关CPN的文献资料做一个综合性的整理,所以最近花了些时间,把乌克兰敖德萨国家电信科学院交通运输部学院的讲义做一个翻译.本课程的翻译不具授权(如有侵权请及时联系,做删除处理) 本课程的标 ...

  9. Gavvmal

    Gavvmal springboot 官方文档说明了两种方式,一种使用插件,直接生成docker镜像,但是这需要本地安装docker环境,但是无论用windows还是mac,本地安装docker都感觉 ...

  10. Markdown表情参考

    emoji-github 文章内容来源 https://github.com/hoangdqvn/emoji-github/blob/master/README.md ️ Emoji-GIT Peop ...