直接维护选k个子段时的最优解似乎也可以做,然而复杂度是O(nk2logn),显然跑不过。

  考虑一种费用流做法。序列里每个点拆成入点和出点,源连入汇连出,入点和出点间连流量1费用ai的边,相邻点出点向入点连流量1费用0的边,整体限流k。

  直接跑当然还不如暴力。观察一下这个做法是在干啥:每次选择费用最大的一段,然后利用反向边将这一段的费用取反。

  这个做法看起来非常贪心(不过费用流本质上也挺贪心的),不过看起来确实是对的。当然从贪心角度就完全不会证了。

  于是考虑利用这种做法维护。那么线段树维护区间最大子段和和最小子段和,取反时交换,剩下的是基本操作了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 100010
int n,m,a[N];
struct data{int L,R,max,maxl,maxr,min,minl,minr,sum,rmax,rmaxid,rmin,rminid,lmax,lmaxid,lmin,lminid,rev;
}tree[N<<],q[];
data merge(data a,data b)
{
data u;
u.rev=;u.L=a.L,u.R=b.R;
u.sum=a.sum+b.sum;
if (a.lmax>a.sum+b.lmax) u.lmax=a.lmax,u.lmaxid=a.lmaxid;
else u.lmax=a.sum+b.lmax,u.lmaxid=b.lmaxid;
if (a.lmin<a.sum+b.lmin) u.lmin=a.lmin,u.lminid=a.lminid;
else u.lmin=a.sum+b.lmin,u.lminid=b.lminid;
if (b.rmax>b.sum+a.rmax) u.rmax=b.rmax,u.rmaxid=b.rmaxid;
else u.rmax=b.sum+a.rmax,u.rmaxid=a.rmaxid;
if (b.rmin<b.sum+a.rmin) u.rmin=b.rmin,u.rminid=b.rminid;
else u.rmin=b.sum+a.rmin,u.rminid=a.rminid;
u.max=a.rmax+b.lmax;u.maxl=a.rmaxid;u.maxr=b.lmaxid;
u.min=a.rmin+b.lmin;u.minl=a.rminid;u.minr=b.lminid;
if (a.max>u.max) u.max=a.max,u.maxl=a.maxl,u.maxr=a.maxr;
if (a.min<u.min) u.min=a.min,u.minl=a.minl,u.minr=a.minr;
if (b.max>u.max) u.max=b.max,u.maxl=b.maxl,u.maxr=b.maxr;
if (b.min<u.min) u.min=b.min,u.minl=b.minl,u.minr=b.minr;
return u;
}
void work(int k)
{
tree[k].rev^=;
tree[k].sum=-tree[k].sum;
swap(tree[k].max,tree[k].min);tree[k].max=-tree[k].max,tree[k].min=-tree[k].min;
swap(tree[k].maxl,tree[k].minl);swap(tree[k].maxr,tree[k].minr);
swap(tree[k].lmax,tree[k].lmin);tree[k].lmax=-tree[k].lmax,tree[k].lmin=-tree[k].lmin;
swap(tree[k].lmaxid,tree[k].lminid);
swap(tree[k].rmax,tree[k].rmin);tree[k].rmax=-tree[k].rmax,tree[k].rmin=-tree[k].rmin;
swap(tree[k].rmaxid,tree[k].rminid);
}
void down(int k){work(k<<),work(k<<|),tree[k].rev=;}
void build(int k,int l,int r)
{
tree[k].L=l,tree[k].R=r;
if (l==r)
{
tree[k].sum=tree[k].max=tree[k].min=tree[k].rmax=tree[k].rmin=tree[k].lmax=tree[k].lmin=a[l];
tree[k].maxl=tree[k].maxr=tree[k].minl=tree[k].minr=tree[k].rmaxid=tree[k].rminid=tree[k].lmaxid=tree[k].lminid=l;
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
tree[k]=merge(tree[k<<],tree[k<<|]);
}
void rev(int k,int l,int r)
{
if (tree[k].L==l&&tree[k].R==r) {work(k);return;}
if (tree[k].rev) down(k);
int mid=tree[k].L+tree[k].R>>;
if (r<=mid) rev(k<<,l,r);
else if (l>mid) rev(k<<|,l,r);
else rev(k<<,l,mid),rev(k<<|,mid+,r);
tree[k]=merge(tree[k<<],tree[k<<|]);
}
void modify(int k,int p,int x)
{
if (tree[k].L==tree[k].R)
{
tree[k].sum=tree[k].max=tree[k].min=tree[k].rmax=tree[k].rmin=tree[k].lmax=tree[k].lmin=x;
tree[k].rev=;
return;
}
if (tree[k].rev) down(k);
int mid=tree[k].L+tree[k].R>>;
if (p<=mid) modify(k<<,p,x);
else modify(k<<|,p,x);
tree[k]=merge(tree[k<<],tree[k<<|]);
}
data query(int k,int l,int r)
{
if (tree[k].L==l&&tree[k].R==r) return tree[k];
if (tree[k].rev) down(k);
int mid=tree[k].L+tree[k].R>>;
if (r<=mid) return query(k<<,l,r);
else if (l>mid) return query(k<<|,l,r);
else return merge(query(k<<,l,mid),query(k<<|,mid+,r));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3272.in","r",stdin);
freopen("bzoj3272.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<=n;i++) a[i]=read();
m=read();
build(,,n);
while (m--)
{
int op=read();
if (op)
{
int l=read(),r=read(),k=read(),ans=;
for (int i=;i<=k;i++)
{
q[i]=query(,l,r);
if (q[i].max>) ans+=q[i].max,rev(,q[i].maxl,q[i].maxr);
else {k=i-;break;}
}
for (int i=;i<=k;i++)
rev(,q[i].maxl,q[i].maxr);
printf("%d\n",ans);
}
else
{
int x=read(),y=read();
modify(,x,y);
}
}
return ;
}

BZOJ3267/3272 KC采花/Zgg吃东西(线段树)的更多相关文章

  1. BZOJ3638[Codeforces280D]k-Maximum Subsequence Sum&BZOJ3272Zgg吃东西&BZOJ3267KC采花——模拟费用流+线段树

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

  2. bzoj3272 Zgg吃东西

    题目描述: bz 题解: 线段树模拟费用流. 想法和种树有点类似. 每次取区间内权值和最大的一段,然后整体乘$-1$,代表再次选中时会去掉之前的影响. 线段树维护一堆东西…… 小白逛公园双倍快乐.乘$ ...

  3. bzoj3272: Zgg吃东西&&3267: KC采花

    口胡 我们容易得到一个费用流的做法,流出k的流量分配给各个点,各个点向下一个点流费用为它的价值的边,然后汇总到ed 观察发现对于流一次,相当于选择了一个区间 如果流了反向边,相当于减去了这一段 可以用 ...

  4. bzoj 3267: KC采花&&3272&&3638&&3502 线段树

    题目大意 给定一个长为n的序列,维护两种操作: 1.单点修改 2.在[l,r]这段区间中取k个互不相交的子段,使子段之和最大. \(n \leq 50000,k \leq 20\) 题解 四倍经验.( ...

  5. 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

    3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 9 ...

  6. BZOJ 2743 【HEOI2012】 采花

    题目链接:采花 这道题一眼看去,一个很显然的想法就是莫队.但是数据范围是\(10^6\)级别的,莫队显然已经过不去了. 其实感觉这道题和以前写过的一道题HH的项链很像.只不过那道题要求的是区间出现次数 ...

  7. 【HEOI2012】采花 BZOJ2743

    Description 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一 ...

  8. 采花 bzoj 2743

    采花(1s 128MB)flower [题目描述] 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整 ...

  9. BZOJ 2743: [HEOI2012]采花

    2743: [HEOI2012]采花 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 2056  Solved: 1059[Submit][Status ...

随机推荐

  1. IIS 配置网站

    IIS 配置网站最常见的问题 1 文件夹权限问题 (C盘 windows下temp文件夹权限问题)2 版本问题 (框架版本问题如4.0 在2.0下运行,4.5在4.0下运行) 3如果是局域网,考虑动态 ...

  2. virtualBox linux centos 挂载u盘 解决乱码

    linux 挂载u盘 环境:虚拟机virtualBox5.2.8 linux centos6.5 64bit 第一步:插入u盘 第二步:virtualBox 设置启用u盘 提示:如果不知道哪个是你u盘 ...

  3. STM平台增加性能测试/稳定性测试部分【二】

    [一]方案 基本上测试针对产品的各项方案大体是如下的: 如上所示,针对产品的性能测试主要步骤如下: 1.造数据,在产品业务流上,产生所需的数据,数据量以(稳定性或者压测指标确定) 2.根据步骤1,设定 ...

  4. 对最近java基础学习的一次小结

    开头想了3分钟,不知道起什么名字好,首先内容有点泛,但也都是基础知识. 对之前所学的java基础知识做了个小结,因为我是跟着网上找的黑马的基础视频看跟着学的,10天的课程硬生生给我看了这么久,也是佛了 ...

  5. MATLAB复制图片时边框大的问题

    当使用MATLAB画图时,需要将图片复制到word中,会发现图片有一个白色的边框,在论文的排版中是一个影响美观的问题 例如: >> x = 0:10; >> y = sin(x ...

  6. SparkRDD编程实战

    通过spark实现点击流日志分析案例 1. 访问的pv package cn.itcast import org.apache.spark.rdd.RDD import org.apache.spar ...

  7. kubeadm源码修改证书时间 -1.13

    编译后~ 链接:https://pan.baidu.com/s/1ofLX1Sv0ZF2yjkJdqf-6rw 提取码:cnbd 已统一与CA证书都是10年 已测试 适用于k8s 1.10 至 1.1 ...

  8. Plasma Cash 合约解读

    作者介绍 虫洞社区·签约作者 steven bai Plasma Cash 合约解读 Plasma Cash 合约解读 1. 合约代码 2. 合约文件简单介绍 3. Plasma Cash 的基础数据 ...

  9. Less 的用法

    1. node.js node.js是一个前端的框架 自带一个包管理工具npm node.js 的安装 官网:http://nodejs.cn/ 在命令行检验是否安装成功 切换到项目目录,初始化了一个 ...

  10. 在写ssh项目时浏览器页面出现http status 404 – not found

    HTTP Status 404 - /streetManager/index.jsp type Status report message /streetManager/index.jsp descr ...