题目链接:戳我

一类典型模型。线段树模拟网络流+区间最大K段和。

因为不会写,所以参考了黄学长的博客。但是我觉得他说得不够详细,所以想好好地解释一下:

前置技能1:区间最大子段和

如果K=1的时候怎么办?大家可以去参考一下蒟蒻的这篇博客:戳我

前置技能2:最长K可重区间集问题

求最长K可重区间集的最大长度。这个是网络流能解决的问题,具体建模请看蒟蒻的这篇博客:戳我

但是我们发现如果用网络流来做的话,显然这道题的数据范围太大了,对于复杂度上届为\(O(n^2m)\)的网络流,不光说仅仅点数就有1e5个,我们连边的话级别也是n*(n-1)/2的。然后我们考虑一下网络流到底是怎么运作的?我们求的是最大费用流,显然不断地增广过程就是不断地在寻找费用最大的区间然后累加到答案里面。但是因为可重叠的最大量为1,所以有时候考虑到更换更优解,我们需要把流量费用退回去,也就把它变成负的。这个过程我们可以用线段树来模拟——

增广的过程我们可以用寻找最大子段和来替代。然后推流可以用线段树区间反转来做。(区间反转如果不会的话。。。或许可以看看luogu的文艺平衡树???)

然后时间复杂度就十分优秀地化简到了\(O(mklogn)\),对于四秒+很快的cf机子应该还是绰绰有余了。

备注一下代码里面的变量意义:

mx:当前值

mn:mx的相反数

嵌套——

maxs:区间最大子段和

sum:区间和(为什么要记录这个我就不说了,大家参考前置技能1)

lx:区间最大前缀子段和

rx:区间最大后缀子段和

p1:区间最大子段和的左区间

p2:区间最大子段和的右区间

因为我们合并的时候有三种情况,其中一种是有可能跨左右区间,所以我们还需要记录lp:区间最大前缀子段和的右端点,rp:区间最大后缀子段和的前端点。

代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
#define MAXN 100010
inline int read()
{
int f=1,x=0; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
int n,m;
int a[MAXN];
struct Node{int lp,rp,lx,rx,sum,maxs,p1,p2;};
struct Node2{int flag,tag;Node mx,mn;}node[MAXN<<2];
vector<pair<int,int> >cur;
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline Node merge(Node x,Node y)
{
Node t;
t.sum=x.sum+y.sum;
if(x.sum+y.lx>x.lx) t.lx=x.sum+y.lx,t.lp=y.lp;
else t.lx=x.lx,t.lp=x.lp;
if(x.rx+y.sum>y.rx) t.rx=x.rx+y.sum,t.rp=x.rp;
else t.rx=y.rx,t.rp=y.rp;
t.maxs=x.maxs,t.p1=x.p1,t.p2=x.p2;
if(y.maxs>t.maxs) t.maxs=y.maxs,t.p1=y.p1,t.p2=y.p2;
if(x.rx+y.lx>t.maxs) t.maxs=x.rx+y.lx,t.p1=x.rp,t.p2=y.lp;
return t;
}
inline void push_up(int x)
{
node[x].mn=merge(node[ls(x)].mn,node[rs(x)].mn);
node[x].mx=merge(node[ls(x)].mx,node[rs(x)].mx);
}
inline void init(Node &x,int pos,int k)
{
x.p1=x.p2=x.lp=x.rp=pos;
x.lx=x.rx=x.maxs=x.sum=k;
}
inline void build(int x,int l,int r)
{
if(l==r)
{
init(node[x].mn,l,-a[l]);
init(node[x].mx,l,a[l]);
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
inline void push_down(int x,int l,int r)
{
if(node[x].tag)
{
swap(node[ls(x)].mn,node[ls(x)].mx);
swap(node[rs(x)].mn,node[rs(x)].mx);
node[ls(x)].tag^=1,node[rs(x)].tag^=1,node[x].tag^=1;
}
}
inline void reverse(int x,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)
{swap(node[x].mn,node[x].mx);node[x].tag^=1;return;}
push_down(x,l,r);
int mid=(l+r)>>1;
if(rr<=mid) reverse(ls(x),l,mid,ll,rr);
else if(mid<ll) reverse(rs(x),mid+1,r,ll,rr);
else reverse(ls(x),l,mid,ll,mid),reverse(rs(x),mid+1,r,mid+1,rr);
push_up(x);
}
inline void update(int x,int l,int r,int pos,int k)
{
if(l==r)
{init(node[x].mx,l,k);init(node[x].mn,l,-k);return;}
int mid=(l+r)>>1;
push_down(x,l,r);
if(pos<=mid) update(ls(x),l,mid,pos,k);
else update(rs(x),mid+1,r,pos,k);
push_up(x);
}
inline Node query(int x,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr) return node[x].mx;
push_down(x,l,r);
int mid=(l+r)>>1;
if(rr<=mid) return query(ls(x),l,mid,ll,rr);
else if(mid<ll) return query(rs(x),mid+1,r,ll,rr);
else return merge(query(ls(x),l,mid,ll,mid),query(rs(x),mid+1,r,mid+1,rr));
}
inline void solve(int x,int l,int r,int k)
{
int cur_ans=0;
cur.clear();
for(int i=1;i<=k;i++)
{
Node t=query(1,1,n,l,r);
if(t.maxs>0) cur_ans+=t.maxs;
else break;
reverse(1,1,n,t.p1,t.p2);
cur.push_back(make_pair(t.p1,t.p2));
}
for(int i=cur.size()-1;i>=0;i--)
reverse(1,1,n,cur[i].first,cur[i].second);
printf("%d\n",cur_ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
n=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
m=read();
while(m--)
{
int op=read();
if(op==1)
{
int u=read(),v=read(),k=read();
solve(1,u,v,k);
}
else
{
int pos=read(),k=read();
update(1,1,n,pos,k);
}
}
return 0;
}

BZOJ3638|CodeForces 280D k-Maximum Subsequence Sum的更多相关文章

  1. 中国大学MOOC-陈越、何钦铭-数据结构-2015秋 01-复杂度2 Maximum Subsequence Sum (25分)

    01-复杂度2 Maximum Subsequence Sum   (25分) Given a sequence of K integers { N​1​​,N​2​​, ..., N​K​​ }. ...

  2. PAT1007:Maximum Subsequence Sum

    1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...

  3. PTA (Advanced Level) 1007 Maximum Subsequence Sum

    Maximum Subsequence Sum Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous su ...

  4. 【DP-最大子串和】PAT1007. Maximum Subsequence Sum

    1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...

  5. PAT Maximum Subsequence Sum[最大子序列和,简单dp]

    1007 Maximum Subsequence Sum (25)(25 分) Given a sequence of K integers { N~1~, N~2~, ..., N~K~ }. A ...

  6. PAT甲 1007. Maximum Subsequence Sum (25) 2016-09-09 22:56 41人阅读 评论(0) 收藏

    1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...

  7. PAT 甲级 1007 Maximum Subsequence Sum (25)(25 分)(0不是负数,水题)

    1007 Maximum Subsequence Sum (25)(25 分) Given a sequence of K integers { N~1~, N~2~, ..., N~K~ }. A ...

  8. PAT 1007 Maximum Subsequence Sum(最长子段和)

    1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...

  9. pat1007. Maximum Subsequence Sum (25)

    1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...

  10. PTA 01-复杂度2 Maximum Subsequence Sum (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/663 5-1 Maximum Subsequence Sum   (25分) Given ...

随机推荐

  1. UVALIVE 4556 The Next Permutation

    4556 The Next PermutationFor this problem, you will write a program that takes a (possibly long) str ...

  2. atom 配置备忘

    插件 vim-mode-plus vim-mode-plus-ex-mode plateformio-ide-terminal    'cmd窗口 docblockr 帮助你快速的生成注释 linte ...

  3. loadView 和 viewDidLoad、viewDidunload 的区别

    loadView 和 viewDidLoad 是 iPhone 开发中肯定要用到的两个方法. 他们都可以用来在视图载入的时候初始化一些内容. 但是他们有什么区别呢? viewDidLoad 方法只有当 ...

  4. SPI子系统分析之四:驱动模块

    内核版本:3.9.5 SPI控制器层(平台相关) 上一节讲了SPI核心层的注册和匹配函数,它是平台无关的.正是在核心层抽象了SPI控制器层的相同部分然后提供了统一的API给SPI设备层来使用.我们这一 ...

  5. ubuntu kylin 设置 wifi

    左上侧  搜索资源 输入 软件和更新  点击软件和更新,点击附加驱动,点击使用无线驱动.

  6. 【Rsync项目实战一】备份全网服务器数据

    目录 [Rsync项目实战]备份全网服务器数据 [企业案例] 1.1 环境部署 1.2 开始部署backup服务器:Rsync服务端过程: 1.3 开始部署nfs01服务器:Rsync客户端过程: [ ...

  7. 阻塞和唤醒线程——LockSupport功能简介及原理浅析

    目录 1.LockSupport功能简介 1.1 使用wait,notify阻塞唤醒线程 1.2 使用LockSupport阻塞唤醒线程 2. LockSupport的其他特色 2.1 可以先唤醒线程 ...

  8. UITextView设置占位文字

    这里只介绍一种,这种方便扩展,可以占位文字颜色. 我们继承一个UITextView: #import <UIKit/UIKit.h> @interface MyTextView : UIT ...

  9. Python——字典与字典方法

    字典是一种通过名字或者关键字引用的得数据结构,其键可以是数字.字符串.元组,这种结构类型也称之为映射.字典类型是Python中唯一內建的映射类型,基本的操作包括如下: (1)len():返回字典中键— ...

  10. SVO详细解读

    SVO详细解读 极品巧克力 前言 接上一篇文章<深度滤波器详细解读>. SVO(Semi-Direct Monocular Visual Odometry)是苏黎世大学Scaramuzza ...