Hdu 5316 Magician (线段树区间合并)

来源:互联网 发布:淘宝天天特价规则 编辑:程序博客网 时间:2024/05/16 07:50

解析:关键是处理奇偶的问题。

正如官方题解所说,本题的子序列实际上可以根据起始数值下标的奇偶性分为四类。
对于每一类,如果你熟悉线段树,那么可以看出这个问题是可以进行区间合并的。
即如果知道一个区间[L, R]两个子区间 [L,mid], [mid+1,R]的信息,我们可以推出[L,R][L,R]的信息。
维护四个值,表示起点终点的下标的奇偶性。

[code]:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;typedef long long LL;const int maxn = 1e5+5;const int INF = 0x3f3f3f3f;struct Node{    LL v0,v1,v2,v3;    Node(){}    Node(LL v0,LL v1,LL v2,LL v3):v0(v0),v1(v1),v2(v2),v3(v3){}    void init(LL v0,LL v1,LL v2,LL v3){        this->v0 = v0;this->v1 = v1;        this->v2 = v2;this->v3 = v3;    }    LL answer(){        return max(max(v0,v1),max(v2,v3));    }};void build(int,int,int) __attribute__((optimize("O3")));void update(int,int,int,int,int) __attribute__((optimize("O3")));Node query(int,int,int,int,int) __attribute__((optimize("O3")));inline bool read(int &ret){    char c;int sgn;    if(c = getchar(),c==EOF) return 0;    while(c != '-'&&(c<'0'||c>'9')) c=getchar();    sgn = (c=='-')?-1:1;    ret = (c=='-')?0:(c-'0');    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');    ret*=sgn;    return 1;}int n,m,a[maxn];LL C[4*maxn][4];void push_up(int rt){    C[rt][0] = max(C[rt<<1][0],max(C[rt<<1|1][0],max(C[rt<<1][0]+C[rt<<1|1][2],C[rt<<1][1]+C[rt<<1|1][0])));    C[rt][1] = max(C[rt<<1][1],max(C[rt<<1|1][1],max(C[rt<<1][1]+C[rt<<1|1][1],C[rt<<1][0]+C[rt<<1|1][3])));    C[rt][2] = max(C[rt<<1][2],max(C[rt<<1|1][2],max(C[rt<<1][2]+C[rt<<1|1][2],C[rt<<1][3]+C[rt<<1|1][0])));    C[rt][3] = max(C[rt<<1][3],max(C[rt<<1|1][3],max(C[rt<<1][2]+C[rt<<1|1][3],C[rt<<1][3]+C[rt<<1|1][1])));}void build(int l,int r,int rt){    if(l == r){        if(l&1) C[rt][0] = a[l],C[rt][3] = -INF;        else C[rt][0] = -INF,C[rt][3] = a[l];        C[rt][1] = C[rt][2] = -INF;        return;    }    int mid = (l+r)>>1;    build(lson);build(rson);    push_up(rt);}void update(int k,int x,int l,int r,int rt){    if(l == r){        if(k&1) C[rt][0] = x;        else C[rt][3] = x;        return;    }    int mid = (l+r)>>1;    if(k <= mid) update(k,x,lson);    else update(k,x,rson);    push_up(rt);}Node query(int a,int b,int l,int r,int rt){    if(a<=l&&r<=b) return Node(C[rt][0],C[rt][1],C[rt][2],C[rt][3]);    int mid = (l+r)>>1;    if(b<=mid) return query(a,b,lson);    else if(a > mid) return query(a,b,rson);    else{        Node ls,rs,s;        ls = query(a,b,lson);rs = query(a,b,rson);        s.v0 = max(max(ls.v0,rs.v0),max(ls.v0+rs.v2,ls.v1+rs.v0));        s.v1 = max(max(ls.v1,rs.v1),max(ls.v1+rs.v1,ls.v0+rs.v3));        s.v2 = max(max(ls.v2,rs.v2),max(ls.v2+rs.v2,ls.v3+rs.v0));        s.v3 = max(max(ls.v3,rs.v3),max(ls.v2+rs.v3,ls.v3+rs.v1));        return s;    }}int main(){    int i,j,cas,op,l,r;    scanf("%d",&cas);    while(cas--){        read(n);read(m);        for(i = 1;i <= n;i++) read(a[i]);        build(1,n,1);        while(m--){            read(op);read(l);read(r);            if(op==0){                printf("%I64d\n",query(l,r,1,n,1).answer());            }else{                update(l,r,1,n,1);            }        }    }    return 0;}


0 0
原创粉丝点击