bzoj 3267: KC采花&&3272&&3638&&3502 线段树
题目大意
给定一个长为n的序列,维护两种操作:
1.单点修改
2.在[l,r]这段区间中取k个互不相交的子段,使子段之和最大.
\(n \leq 50000,k \leq 20\)
题解
四倍经验.(但我的写法太丑过不了3502)
我们可以很简单地构建出一个最大费用最大流模型
把每个点拆点,然后S,T分别连接即可
但是这道题n达到50000,直接上费用流绝对T的不要不要的
我们想一下这样费用流的时候都在干什么
每次找出一个费用最大的区间...把答案加上费用之和...把所有的费用取反...
我们发现我们可以用线段树维护这个过程!
支持最大子段和查询和反转操作
所以我们维护一个最大子段和和最小子段和即可!!
啥?好像好要维护取到最大子段和和最小子段和时的端点?
啥?要维护从左端点的开始的最大子段和和从右端点开始的最大子段和?
好麻烦啊。。。估计是我写丑了...所以3502才被卡空间了...
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 100010;
const int inf = 0x3f3f3f3f;
struct Node{
int mx,lmx,rmx,lx,rx,plx,prx;
int mn,lmn,rmn,ln,rn,pln,prn;
int sum,rev;
Node(){
mx = lmx = rmx = -inf;
mn = lmn = rmn = inf;
sum = lx = rx = ln = rn = rev = 0;
}
inline void set(int x,int p){
rev = 0;mx = lmx = rmx = mn = lmn = rmn = sum = x;
lx=rx=plx=prx=ln=rn=pln=prn = p;
}
inline void reve(){
swap(mx,mn);swap(lmn,lmx);swap(rmn,rmx);
swap(lx,ln);swap(rx,rn);swap(plx,pln);swap(prx,prn);
mx = -mx;mn = -mn;
lmn = -lmn;lmx = -lmx;
rmx = -rmx;rmn = -rmn;
sum = -sum;rev ^= 1;
}
Node friend operator + (const Node &l,const Node &r){
Node c;
c.sum = l.sum + r.sum;
c.lmx = max(l.lmx,l.sum+max(r.lmx,0));
c.rmx = max(r.rmx,r.sum+max(l.rmx,0));
c.mx = max(max(l.mx,r.mx),max(l.rmx+max(0,r.lmx),max(l.rmx,0)+r.lmx) );
if(c.lmx == l.lmx) c.plx = l.plx;
else c.plx = r.plx;
if(c.rmx == r.rmx) c.prx = r.prx;
else c.prx = l.prx;
if(c.mx == l.mx) c.lx = l.lx,c.rx = l.rx;
else if(c.mx == r.mx) c.lx = r.lx,c.rx = r.rx;
else if(c.mx == l.rmx+r.lmx)c.lx = l.prx,c.rx = r.plx;
c.lmn = min(l.lmn,l.sum+min(r.lmn,0));
c.rmn = min(r.rmn,r.sum+min(l.rmn,0));
c.mn = min(min(l.mn,r.mn),min(l.rmn+min(0,r.lmn),min(l.rmn,0)+r.lmn) );
if(c.lmn == l.lmn) c.pln = l.pln;
else c.pln = r.pln;
if(c.rmn == r.rmn) c.prn = r.prn;
else c.prn = l.prn;
if(c.mn == l.mn) c.ln = l.ln,c.rn = l.rn;
else if(c.mn == r.mn) c.ln = r.ln,c.rn = r.rn;
else if(c.mn == l.rmn+r.lmn) c.ln = l.prn,c.rn = r.pln;
}
}T[maxn<<2];
int a[maxn];
inline void pushdown(int rt,int l,int r){
if(T[rt].rev == 0) return;
T[rt].rev = 0;
if(l == r) return;
T[rt<<1].reve();T[rt<<1|1].reve();
}
void build(int rt,int l,int r){
if(l == r){
T[rt].set(a[l],l);
return;
}int mid = l+r >> 1;
build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
T[rt] = T[rt<<1] + T[rt<<1|1];
}
void modify(int rt,int l,int r,int pos,int val){
if(l == r){
T[rt].set(val,l);
return;
}
int mid = l+r >> 1;
pushdown(rt,l,r);
if(pos <= mid) modify(rt<<1,l,mid,pos,val);
else modify(rt<<1|1,mid+1,r,pos,val);
T[rt] = T[rt<<1] + T[rt<<1|1];
}
Node query(int rt,int l,int r,int L,int R){
if(L <= l && r <= R) return T[rt];
int mid = l+r >> 1;
pushdown(rt,l,r);
if(R <= mid) return query(rt<<1,l,mid,L,R);
if(L > mid) return query(rt<<1|1,mid+1,r,L,R);
return query(rt<<1,l,mid,L,R) + query(rt<<1|1,mid+1,r,L,R);
}
void rever(int rt,int l,int r,int L,int R){
if(L <= l && r <= R){T[rt].reve();return;}
int mid = l+r >> 1;
pushdown(rt,l,r);
if(L <= mid) rever(rt<<1,l,mid,L,R);
if(R > mid) rever(rt<<1|1,mid+1,r,L,R);
T[rt] = T[rt<<1] + T[rt<<1|1];
}
struct seg{
int l,r;
seg(int l=0,int r=0){this->l=l;this->r=r;}
}sta[22];
int top,n;
inline int spfa(int l,int r,int num){
top = 0;int ret = 0;
while(num--){
Node x = query(1,1,n,l,r);
if(x.mx < 0) break;
sta[++top] = seg(x.lx,x.rx);
ret += x.mx;
rever(1,1,n,x.lx,x.rx);
}
while(top){
rever(1,1,n,sta[top].l,sta[top].r);
--top;
}
return ret;
}
int main(){
read(n);
for(int i=1;i<=n;++i) read(a[i]);
build(1,1,n);
int m;read(m);
int op,l,r,k;
while(m--){
read(op);read(l);read(r);
if(op == 0){
modify(1,1,n,l,r);
}else{
read(k);
printf("%d\n",spfa(l,r,k));
}
}
getchar();getchar();
return 0;
}
bzoj 3267: KC采花&&3272&&3638&&3502 线段树的更多相关文章
- bzoj3272: Zgg吃东西&&3267: KC采花
口胡 我们容易得到一个费用流的做法,流出k的流量分配给各个点,各个点向下一个点流费用为它的价值的边,然后汇总到ed 观察发现对于流一次,相当于选择了一个区间 如果流了反向边,相当于减去了这一段 可以用 ...
- BZOJ3638[Codeforces280D]k-Maximum Subsequence Sum&BZOJ3272Zgg吃东西&BZOJ3267KC采花——模拟费用流+线段树
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
- BZOJ.3307.雨天的尾巴(dsu on tree/线段树合并)
BZOJ 洛谷 \(dsu\ on\ tree\).(线段树合并的做法也挺显然不写了) 如果没写过\(dsu\)可以看这里. 对修改操作做一下差分放到对应点上,就成了求每个点子树内出现次数最多的颜色, ...
- 洛谷 P2056 BZOJ 2743 [HEOI2012]采花
//表示真的更喜欢洛谷的题面 题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 ...
- BZOJ 2743: [HEOI2012]采花
2743: [HEOI2012]采花 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 2056 Solved: 1059[Submit][Status ...
- BZOJ 2743: [HEOI2012]采花( 离线 + BIT )
处理出每个数下一个出现的位置, 然后按左端点排序回答询问.处理当前数去除的影响 ------------------------------------------------------------ ...
- BZOJ 2743: [HEOI2012]采花 离线树状数组
2743: [HEOI2012]采花 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2743 Description 萧芸斓是Z国的公主, ...
- BZOJ 5326 [JSOI2017]博弈 (模拟费用流、线段树)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5326 题解 终于成为第8个A掉这题的人--orz tzw神仙早我6小时 本以为这东西常数 ...
- [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】
题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...
随机推荐
- client交互技术简单介绍
随着网络应用的不断丰富,client交互技术也如雨后春笋一般,遍地开花. 正是这些技术的支持,我们的互联网世界变得更加丰富多彩.一个浏览器上.不用说是简单的动画效果,就是一个Office应用也能顺畅的 ...
- servletResponse 文件下载
package response; import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOEx ...
- Ubuntu 14.04lts安装vncserver
之前有在centos上安装过非常多次vncserver,也写过一个centos 7上的安装文档.近来常识了好几次在ubuntu上安装都没有成功,这次最终搞定了.ubuntu自带的桌面是unity.这个 ...
- (个人开源)ffpanel --ffmpeg的GUI,让ffmpeg离开黑黑的命令行
程序及源代码下载地址 :https://github.com/langsim/ffpanel
- 18- php Redis扩展编译
一:php扩展编译Redis :wget http://pecl.php.net/get/redis-2.2.5.tgz :tar -zxvf redis-.tgz :cd redis- :/usr/ ...
- android 自定图库(转)
githup: https://github.com/pengjianbo/GalleryFinal GalleryFinal简介 Android自定义相册,实现了拍照.图片选择(单选/多选). 裁剪 ...
- 【文献阅读】Augmenting Supervised Neural Networks with Unsupervised Objectives-ICML-2016
一.Abstract 从近期对unsupervised learning 的研究得到启发,在large-scale setting 上,本文把unsupervised learning 与superv ...
- iOS 键盘变中文
plist文件添加 Localizations 添加一项字段Chinese (simplified)
- HUD3689 Infinite monkey theorem
Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包
[BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...