题目链接:戳我

一类典型模型。线段树模拟网络流+区间最大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. Python nonlocal 与 global 关键字解析

    nonlocal 首先,要明确 nonlocal 关键字是定义在闭包里面的.请看以下代码: x = 0 def outer(): x = 1 def inner(): x = 2 print(&quo ...

  2. avalon1.3的新特性预览

    avalon1.2的性能优化风暴很快就告一段落,入职也快一个月了,许多乱七八糟的事也少了下来,估计未来一个月会有许多好东呈现给大家. 首先是一个性能检测工具.由于MVVM是将原本由人脑干的事,转到各种 ...

  3. Spyder kernel died 错误

    Keras 2.2.4版本和 tensorflow1.2.1 版本不兼容导致的错误.降低Keras 为2.1.2版本 import keras 出现: Using TensorFlow backend ...

  4. DEV上肤

    1,在Main中加入此语句DevExpress.UserSkins.BonusSkins.Register();SkinManager.EnableFormSkins();DevExpress.Loo ...

  5. Spring Data JPA + layui的前台分页插件layPage实现页面的分页

    一.后台代码: 1.1 controller层代码 @RequestMapping("/xxxxxx") public String showInformationCode(Str ...

  6. MySQL 时间函数加减计算

    一.MySQL 获得当前日期时间 函数 1.1 获得当前日期 + 时间(date + time) 函数:now() mysql> select now();+———————+| now() |+ ...

  7. JAVA 上加密算法的实现用例,MessageDigest介绍

    第 1 章基础知识 1.1. 单钥密码体制 单钥密码体制是一种传统的加密算法,是指信息的发送方和接收方共同使用同一把密钥进行加解密. 通常 , 使用的加密算法 比较简便高效 , 密钥简短,加解密速度快 ...

  8. Partial Functions(偏函数)

    如果你想定义一个函数,而让它只接受和处理其参数定义域范围内的子集,对于这个参数范围外的参数则抛出异常,这样的函数就是偏函数(顾名思异就是这个函数只处理传入来的部分参数). 偏函数是个特质其的类型为Pa ...

  9. code1047 邮票面值设计

    dfs+dp dfs枚举每种情况,每层递归确定第k个数i:i = a[k-1]+1 to a[k-1]*n+1 当枚举完一个序列时,使用check()测试它能达到的max 使用dp.设dp[i]为凑成 ...

  10. 巧用渐变色打造精致移动端APP

    渐变色是指某个物体的颜色从明到暗,或由深转浅,或是从一个色彩缓慢过渡到另一个色彩,充满变幻无穷的神秘浪漫气息的颜色.在扁平化设计刚刚兴起时,渐变是设计师们避之不及的设计手法.然而自从Instagram ...