BZOJ3638|CodeForces 280D k-Maximum Subsequence Sum
题目链接:戳我
一类典型模型。线段树模拟网络流+区间最大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的更多相关文章
- 中国大学MOOC-陈越、何钦铭-数据结构-2015秋 01-复杂度2 Maximum Subsequence Sum (25分)
01-复杂度2 Maximum Subsequence Sum (25分) Given a sequence of K integers { N1,N2, ..., NK }. ...
- PAT1007:Maximum Subsequence Sum
1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...
- PTA (Advanced Level) 1007 Maximum Subsequence Sum
Maximum Subsequence Sum Given a sequence of K integers { N1, N2, ..., NK }. A continuous su ...
- 【DP-最大子串和】PAT1007. Maximum Subsequence Sum
1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...
- PAT Maximum Subsequence Sum[最大子序列和,简单dp]
1007 Maximum Subsequence Sum (25)(25 分) Given a sequence of K integers { N~1~, N~2~, ..., N~K~ }. A ...
- 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 ...
- 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 ...
- PAT 1007 Maximum Subsequence Sum(最长子段和)
1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...
- pat1007. Maximum Subsequence Sum (25)
1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...
- 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 ...
随机推荐
- 索引(index)
#创建索引 create index index_name_pass on student(name,pass); create index index_name_id on student(name ...
- 【POJ1811】Prime Test
[题目大意] 若n是素数,输出“Prime”,否则输出n的最小素因子,(n<=2^54) [题解] 和bzoj3667差不多,知识这道题没那么坑. 直接上Pollord_Rho和Rabin_Mi ...
- 144. Binary Tree Preorder Traversal (Tree, Stack)
Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary t ...
- MySQL多表查询回顾
----------------------siwuxie095 MySQL 多表查询回顾 以客户和联系人为例(一对多) 1.内连接 /*内连接写法一*/ select * from t_custom ...
- SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存
1 环境说明 JDK: 1.8 MAVEN: 3. SpringBoot: 2.0.4 2 SpringBoot集成Mybatis-Plus 2.1 创建SpringBoot 利用IDEA创建Spri ...
- DBArtist之Oracle入门第1步: 如何安装Oracle 11g
操作系统: Windows 7 数据库 : Oracle 11gR2 第一步: 下载Oracle安装包 Oracle官网: https://www.oracle.com/index.html ...
- 14-敌兵布阵(HDU1166线段树 & 树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory ...
- shiro 权限集成Ehcache 配置 学习记录(二)
1.加入依赖 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-eh ...
- 4418开发板读取u盘说明
1.插上u盘后会在dev下生成两个文件db db1 将db1挂载即可访问..
- ubuntu14.04 64 位 vmware tools 问题2
当提示说open-vm-tools版本太低时可以这样解决 0.使用最新版本12.5的vmware player. 1.sudo apt-get autoremove open-vm-dkms open ...