题目大意

给定一个长为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 线段树的更多相关文章

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

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

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

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

  3. BZOJ.3307.雨天的尾巴(dsu on tree/线段树合并)

    BZOJ 洛谷 \(dsu\ on\ tree\).(线段树合并的做法也挺显然不写了) 如果没写过\(dsu\)可以看这里. 对修改操作做一下差分放到对应点上,就成了求每个点子树内出现次数最多的颜色, ...

  4. 洛谷 P2056 BZOJ 2743 [HEOI2012]采花

    //表示真的更喜欢洛谷的题面 题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 ...

  5. BZOJ 2743: [HEOI2012]采花

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

  6. BZOJ 2743: [HEOI2012]采花( 离线 + BIT )

    处理出每个数下一个出现的位置, 然后按左端点排序回答询问.处理当前数去除的影响 ------------------------------------------------------------ ...

  7. BZOJ 2743: [HEOI2012]采花 离线树状数组

    2743: [HEOI2012]采花 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2743 Description 萧芸斓是Z国的公主, ...

  8. BZOJ 5326 [JSOI2017]博弈 (模拟费用流、线段树)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5326 题解 终于成为第8个A掉这题的人--orz tzw神仙早我6小时 本以为这东西常数 ...

  9. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...

随机推荐

  1. Struts2学习四----------动态方法调用

    © 版权声明:本文为博主原创文章,转载请注明出处 Struts2动态方法调用 - 默认:默认执行方法中的execute方法,若指定类中没有该方法,默认返回success <package nam ...

  2. 处理字符串的一些C函数

    注意:以下函数都包含在ctype.h头文件中 1.isalpha函数 用来判断得到的参数是不是字母 #include<stdio.h> #include<ctype.h> in ...

  3. erlang中通过ip和子网掩码,计算地址范围 【二进制和十进制的转换】

    在程序中,难免用的二进制和十进制之间的转换.遇到一个场景,通过ip和子网掩码,计算地址范围. 而地址范围为:网络地址+1—— 广播地址 -1 .  网络地址即ip和子网掩码的与的位运算.广播地址为:网 ...

  4. Linux 批量替换的一种实现方式

    替换某目录下所有文件中的某个字符: sed -i 's/origin_str/new_str/g' `grep origin_str -rl ./` origin_str:被替换的字符串: new_s ...

  5. 【TensorFlow-windows】(六) CNN之Alex-net的测试

    主要内容: 1.CNN之Alex-net的测试 2.该实现中的函数总结 平台: 1.windows 10 64位 2.Anaconda3-4.2.0-Windows-x86_64.exe (当时TF还 ...

  6. NuGet管理工具安装

    安装完成后VS重启即可

  7. iOSPOI检索详细总结

    iOS百度地图路径规划和POI检索详细总结 路径规划.png 百度地图的使用 百度地图API的导入网上说了许多坑,不过我遇到的比较少,这里就放两个比较常见的吧.坑一: 奥联WIFI_xcodeproj ...

  8. delphi 颜色 引用http://www.cnblogs.com/del/archive/2008/02/19/1073568.html

    颜色名称   颜色效果   Hex HTML clBlack   $000000 #000000 clMaroon   $000080 #800000 clGreen   $008000 #00800 ...

  9. 再看python多线程------threading模块

    现在把关于多线程的能想到的需要注意的点记录一下: 关于threading模块: 1.关于 传参问题 如果调用的子线程函数需要传参,要在参数后面加一个“,”否则会抛参数异常的错误. 如下: for i ...

  10. 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈

    [BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...