# BZOJ 3638 k-Maximum Subsequence Sum

## Description

1.修改某个数的值
2.读入l,r,k，询问在[l,r]内选不相交的不超过k个子段，最大的和是多少。

## Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=100007;
int i,j,k,l,n,m,ans,o,tt;
int a[maxn];
struct haofana{
int l,r,o;
friend haofana operator +(haofana x,haofana y){
haofana z;
z.l=min(x.l,y.l);z.r=max(y.r,x.r);
z.o=x.o+y.o;
return z;
}
friend bool operator <(haofana x,haofana y){
return x.o<y.o;
}
}ans1,b[200];
struct node{
haofana lda,lxiao,rda,rxiao,sum,xiao,da;
bool lazy;
}t[maxn*5];
void merge(node &x,node y,node z){
x.sum=y.sum+z.sum;
x.lda=max(y.lda,y.sum+z.lda);
x.rda=max(z.rda,z.sum+y.rda);
x.lxiao=min(y.lxiao,y.sum+z.lxiao);
x.rxiao=min(z.rxiao,z.sum+y.rxiao);
x.da=max(y.da,z.da);
x.da=max(x.da,y.rda+z.lda);
x.xiao=min(y.xiao,z.xiao);
x.xiao=min(x.xiao,y.rxiao+z.lxiao);
x.lazy=0;
}
void fan(int x){
t[x].sum.o*=-1;
t[x].da.o*=-1;
t[x].lda.o*=-1;
t[x].rda.o*=-1;
t[x].lxiao.o*=-1;
t[x].rxiao.o*=-1;
t[x].lazy^=1;
t[x].xiao.o*=-1;
swap(t[x].da,t[x].xiao);
swap(t[x].lda,t[x].lxiao);
swap(t[x].rda,t[x].rxiao);

}
void lazydown(int x){
if(t[x].lazy){
fan(x*2);
fan(x*2+1);
t[x].lazy=0;
}
}
void newdian(node &x,int l,int r,int p){
x.lda.l=x.lxiao.l=x.rda.l=x.rxiao.l=x.sum.l=x.xiao.l=x.da.l=l;
x.lda.r=x.lxiao.r=x.rda.r=x.rxiao.r=x.sum.r=x.xiao.r=x.da.r=r;
x.lda.o=x.lxiao.o=x.rda.o=x.rxiao.o=x.sum.o=x.xiao.o=x.da.o=p;
x.lazy=0;
}
void build(int x,int l,int r){
if(l==r){
newdian(t[x],l,r,a[l]);
}
else{
int mid=(l+r)/2;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
merge(t[x],t[x*2],t[x*2+1]);
}
}
void change(int x,int l,int r,int y,int z){
if(l==r){
newdian(t[x],l,r,z);
}
else{
int mid=(l+r)/2;
lazydown(x);
if(y<=mid)change(x*2,l,mid,y,z);else change(x*2+1,mid+1,r,y,z);
merge(t[x],t[x*2],t[x*2+1]);
}
}
node find(int x,int l,int r,int y,int z){
node q;
if(l==y&&r==z){
return t[x];
}
else{
lazydown(x);
int mid=(l+r)/2;
if(z<=mid)return find(x*2,l,mid,y,z);else if (mid<y)return find(x*2+1,mid+1,r,y,z);
else{
merge(q,find(x*2,l,mid,y,mid),find(x*2+1,mid+1,r,mid+1,z));
return q;
}
}
}
void negatea(int x,int l,int r,int y,int z){
if(l==y&&r==z){
fan(x);
}
else{
lazydown(x);
int mid=(l+r)/2;
if(z<=mid)negatea(x*2,l,mid,y,z);else if(mid<y)negatea(x*2+1,mid+1,r,y,z);
else{
negatea(x*2,l,mid,y,mid);
negatea(x*2+1,mid+1,r,mid+1,z);
}
merge(t[x],t[x*2],t[x*2+1]);
}
}
int main(){
freopen("0.in","r",stdin);
scanf("%d",&n);
fo(i,1,n){
scanf("%d",&a[i]);
}
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d",&k);
ans=0;
if(k){
scanf("%d%d%d",&l,&tt,&o);
int u=0;
while(o--){
ans1=find(1,1,n,l,tt).da;
if(ans1.o<0)break;
ans+=ans1.o;
b[++u]=ans1;
negatea(1,1,n,ans1.l,ans1.r);
}
printf("%d\n",ans);

while(u){
negatea(1,1,n,b[u].l,b[u].r);
u--;
}
}else{
scanf("%d%d",&l,&tt);
change(1,1,n,l,tt);
}
}
}