k-Maximum Subsequence Sum

来源:互联网 发布:微信做淘宝客 编辑:程序博客网 时间:2024/05/20 14:18

k-Maximum Subsequence Sum

题目描述:
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3638

题解

数据较小时,考虑费用流。为什么我没想到(雾)。
由于本题n较大,所以考虑进行人工增广。
用线段树维护区间最大子串,每次增广将其取反即可。
本题有4倍经验!!!

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<ctime>#include<algorithm>#define N 100010 using namespace std;int n,m,ans,tot,s[N];struct info{int sum,ml,mr,num,pl,pr,l,r;}q[22];struct node{int tag;info minn,maxn;}t[N*4];class seg_tree{  void change(int x)  {    t[x].tag^=1;swap(t[x].maxn,t[x].minn);  }  void pushdown(int x)  {    if(!t[x].tag)return;    int lc=x<<1,rc=lc+1;t[x].tag=0;    change(lc);change(rc);  }  info merge(info a,info b)  {    info res;res.sum=a.sum+b.sum;    res.ml=a.ml;res.mr=b.mr;    res.pl=a.pl;res.pr=b.pr;    if(a.sum+b.ml>res.ml)      res.ml=a.sum+b.ml,res.pl=b.pl;    if(b.sum+a.mr>res.mr)      res.mr=b.sum+a.mr,res.pr=a.pr;    res.num=a.mr+b.ml;res.l=a.pr;res.r=b.pl;    if(a.num>res.num)      res.num=a.num,res.l=a.l,res.r=a.r;    if(b.num>res.num)      res.num=b.num,res.l=b.l,res.r=b.r;    return res;  }  void update(int x)  {    int lc=x<<1,rc=lc+1;    t[x].maxn=merge(t[lc].maxn,t[rc].maxn);     t[x].minn=merge(t[lc].minn,t[rc].minn);   }  public:  void build(int x,int l,int r)  {    t[x].tag=0;    if(l==r)    {      info res;      res.sum=res.num=res.ml=res.mr=s[l];      res.l=res.r=res.pl=res.pr=l;      t[x].maxn=res;      res.sum=res.num=res.ml=res.mr=-s[l];      t[x].minn=res;      return;    }    int mid=l+r>>1,lc=x<<1,rc=lc+1;    build(lc,l,mid);build(rc,mid+1,r);    update(x);  }  void modify(int x,int l,int r,int des,int val)  {    if(l==r)    {      info res;      res.sum=res.num=res.ml=res.mr=val;      res.l=res.r=res.pl=res.pr=l;      t[x].maxn=res;      res.sum=res.num=res.ml=res.mr=-val;      t[x].minn=res;      return;    }    int mid=l+r>>1,lc=x<<1,rc=lc+1;    pushdown(x);    if(des<=mid)modify(lc,l,mid,des,val);    else modify(rc,mid+1,r,des,val);    update(x);  }  void reverse(int x,int l,int r,int ql,int qr)  {    if(ql<=l&&r<=qr){change(x);return;}    int mid=l+r>>1,lc=x<<1,rc=lc+1;    pushdown(x);    if(ql<=mid)reverse(lc,l,mid,ql,qr);    if(qr>mid)reverse(rc,mid+1,r,ql,qr);    update(x);  }  info qry(int x,int l,int r,int ql,int qr)  {    if(ql<=l&&r<=qr)return t[x].maxn;    int mid=l+r>>1,lc=x<<1,rc=lc+1;    pushdown(x);    if(qr<=mid)return qry(lc,l,mid,ql,qr);    if(ql>mid)return qry(rc,mid+1,r,ql,qr);    return merge(qry(lc,l,mid,ql,qr),qry(rc,mid+1,r,ql,qr));   }}T;int main(){  int tp,x,y,k;  scanf("%d",&n);  for(int i=1;i<=n;i++)scanf("%d",&s[i]);  T.build(1,1,n);  scanf("%d",&m);  for(int i=1;i<=m;i++)  {    scanf("%d%d%d",&tp,&x,&y);    if(tp==1)    {      scanf("%d",&k);ans=0;tot=0;      while(k--)      {        info p=T.qry(1,1,n,x,y);        if(p.num<0)break;        T.reverse(1,1,n,p.l,p.r);        ans+=p.num;q[++tot]=p;       }      for(int i=1;i<=tot;i++)        T.reverse(1,1,n,q[i].l,q[i].r);      printf("%d\n",ans);    }    else T.modify(1,1,n,x,y);  }  return 0;}
0 0
原创粉丝点击