HDU 5316

来源:互联网 发布:linux下复制文件夹 编辑:程序博客网 时间:2024/05/17 06:55

HDU 5316

题意是给一个数列,有两种操作,一是询问[L,R]的最大子序列和,二是改变某个位置的值。单点修改,区间查询,很显然的线段树。关键在于,询问时的最大子序列要求相邻元素的在原序列中的位置奇偶性不同。
序列的奇偶性根据首位和末位的奇偶性最多就四种情况,奇奇,偶偶,奇偶,偶奇。
那么线段树中的每个节点保存这四种序列的最大和即可,并注意合并。

#include<bits/stdc++.h>#define LS (root<<1)#define RS ((root<<1)|1)#define LSON LS,l,mid#define RSON RS,(mid+1),r#define MID mid=((l+r)/2)#define LL long long#define mm(a,b) memset(a,b,sizeof(a))using namespace std;const int maxn=1e5+5;const LL Inf=1e18;struct sum{    LL odd_odd, odd_even, even_odd, even_even;    sum(){odd_odd=-Inf; odd_even=-Inf; even_odd=-Inf; even_even=-Inf;}};sum s[maxn<<2];LL a[maxn];void pushup(int root){    s[root].odd_odd=max(max(s[LS].odd_odd, s[RS].odd_odd), max(s[LS].odd_odd+s[RS].even_odd, s[LS].odd_even+s[RS].odd_odd));    s[root].odd_even=max(max(s[LS].odd_even, s[RS].odd_even), max(s[LS].odd_odd+s[RS].even_even, s[LS].odd_even+s[RS].odd_even));    s[root].even_odd=max(max(s[LS].even_odd, s[RS].even_odd), max(s[LS].even_odd+s[RS].even_odd, s[LS].even_even+s[RS].odd_odd));    s[root].even_even=max(max(s[LS].even_even, s[RS].even_even), max(s[LS].even_even+s[RS].odd_even, s[LS].even_odd+s[RS].even_even));}void build(int root,int l,int r){    s[root].odd_odd=s[root].odd_even=s[root].even_odd=s[root].even_even=-Inf;    if(l==r){        if(l%2)            s[root].odd_odd=a[l];        else            s[root].even_even=a[l];        return;    }    int mid=(l+r)>>1;    build(LSON);    build(RSON);    pushup(root);}void update(int root,int l,int r,int pos,LL v){    if(l==r){        if(l%2)            s[root].odd_odd=v;        else            s[root].even_even=v;        return;    }    int mid=(l+r)>>1;    if(pos<=mid) update(LSON, pos, v);    else update(RSON, pos, v);    pushup(root);}sum unite(sum lsum, sum rsum){    sum ret;    ret.odd_odd=max(max(lsum.odd_odd, rsum.odd_odd), max(lsum.odd_odd+rsum.even_odd, lsum.odd_even+rsum.odd_odd));    ret.odd_even=max(max(lsum.odd_even, rsum.odd_even), max(lsum.odd_even+rsum.odd_even, lsum.odd_odd+rsum.even_even));    ret.even_odd=max(max(lsum.even_odd, rsum.even_odd), max(lsum.even_odd+rsum.even_odd, lsum.even_even+rsum.odd_odd));    ret.even_even=max(max(lsum.even_even, rsum.even_even), max(lsum.even_even+rsum.odd_even, lsum.even_odd+rsum.even_even));    return ret;}sum query(int root,int l,int r,int L,int R){    if(L<=l&&r<=R){        return s[root];    }    int mid=(l+r)>>1;    sum lsum, rsum;    if(L<=mid) lsum=query(LSON, L, R);    if(R>mid) rsum=query(RSON, L, R);    return unite(lsum,rsum);}int main(){    int T, n, m;    int op, L, R;    LL v;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n, &m);        for(int i=1;i<=n;i++)            scanf("%lld",&a[i]);        build(1,1,n);        for(int i=0;i<m;i++){            scanf("%d",&op);            if(op==0){                scanf("%d%d", &L, &R);                sum ans=query(1,1,n,L,R);                printf("%lld\n",max(max(ans.odd_odd, ans.odd_even), max(ans.even_even, ans.even_odd)));            }else{                scanf("%d%lld",&L, &v);                update(1,1,n,L,v);            }        }    }    return 0;}
0 0
原创粉丝点击