poj 2750

来源:互联网 发布:关于矩阵的论文 编辑:程序博客网 时间:2024/05/21 17:58

线段树

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int n,q;struct node{    int l,r;    int sum;    int amax,amin;    //区间最大、小序列和    int lmax,rmax;    //区间最左、右连续最大和    int lmin,rmin;    //区间最左、右连续最小和}tree[300000];void build(int s,int t,int id){    tree[id].l=s,tree[id].r=t;    tree[id].sum=0;    tree[id].amax=tree[id].lmax=tree[id].rmax=-1000000000;    tree[id].amin=tree[id].lmin=tree[id].rmin= 1000000000;    if(s!=t){        int mid=(s+t)>>1;        build(s,mid,id*2);        build(mid+1,t,id*2+1);    }}void updatelength(int id){    tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;    tree[id].amax=max(max(tree[id*2].amax,tree[id*2+1].amax),tree[id*2].rmax+tree[id*2+1].lmax);    tree[id].amin=min(min(tree[id*2].amin,tree[id*2+1].amin),tree[id*2].rmin+tree[id*2+1].lmin);    tree[id].lmax=tree[id*2].lmax;    tree[id].lmin=tree[id*2].lmin;    tree[id].rmax=tree[id*2+1].rmax;    tree[id].rmin=tree[id*2+1].rmin;    if(tree[id*2].lmax<tree[id*2].sum+tree[id*2+1].lmax)         //注意在更新tree[id*2].lmax等这四个变量时有一些问题        tree[id].lmax=tree[id*2].sum+tree[id*2+1].lmax;    if(tree[id*2].lmin>tree[id*2].sum+tree[id*2+1].lmin)        tree[id].lmin=tree[id*2].sum+tree[id*2+1].lmin;    if(tree[id*2+1].rmax<tree[id*2+1].sum+tree[id*2].rmax)        tree[id].rmax=tree[id*2+1].sum+tree[id*2].rmax;    if(tree[id*2+1].rmin>tree[id*2+1].sum+tree[id*2].rmin)        tree[id].rmin=tree[id*2+1].sum+tree[id*2].rmin;}void update(int s,int tem,int id){    if(tree[id].l==tree[id].r){        tree[id].sum=tem;        tree[id].amax=tree[id].amin=tree[id].lmax=tree[id].lmin=tree[id].rmax=tree[id].rmin=tem;        return ;    }    int mid=(tree[id].l+tree[id].r)>>1;    if(mid>=s)        update(s,tem,id*2);    else        update(s,tem,id*2+1);    updatelength(id);}int main(){    int i,j,pos,tem;    scanf("%d",&n);    build(1,n,1);    for(i=1;i<=n;i++){        scanf("%d",&tem);        update(i,tem,1);    }    scanf("%d",&q);    for(i=1;i<=q;i++){        scanf("%d %d",&pos,&tem);        update(pos,tem,1);        if(tree[1].amax==tree[1].sum)            printf("%d\n",tree[1].amax-tree[1].amin);        else if(tree[1].amax>=tree[1].sum-tree[1].amin)          //考虑到环的性质,最左边的线段连接最右边的线段这种情况也可能产生最大值            printf("%d\n",tree[1].amax);        else if(tree[1].amax<tree[1].sum-tree[1].amin)          //但是此时最大值为环总和减去最小连续和,而不是tree[1].lmax+tree[1].rmax            printf("%d\n",tree[1].sum-tree[1].amin);    }}


 

原创粉丝点击