hdu 3397 Sequence operation

来源:互联网 发布:js pdf在线阅读 编辑:程序博客网 时间:2024/05/21 08:28

比较恶心的线段树。感觉出线段树真随意,几种简单操作一结合就是一很恶心的 T T 。

这个就是。覆盖操作+异或操作。

各算各的,但是有个地方需要注意下,就是tag传递的先后问题。我一直WA在这里,后看别人解释,如果覆盖的话,那么异或已经没有用了,把异或标记为0即可。改了之后AC。

因为先覆盖再异或和先异或再覆盖的结果可能是不同的,所以必须确定,是怎么的一种传递方法。

传递的时候,如果是覆盖传递,那么子节点的异或失效。如果是异或传递,无影响。(因为存在异或,说明之前不会有覆盖经过这里)。

本来230+行,后来改改,改到210+ = =。。还是很长。。1300+MS,很慢 T T.。

//第三个版本,我真是越来越懒了。。

#include <queue>#include <stack>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>#define MID(x,y) ( ( x + y ) >> 1 )#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )#define BUG puts("here!!!")using namespace std;const int MAX = 100010;struct Tnode{int l,r,lb,rb,lw,rw,sb,sw,sum;bool t;short cover;int mid() { return MID(l,r);}int len() { return r - l;}bool in(int ll,int rr) { return l >= ll && r <= rr; }void lr(int ll,int rr){ l = ll; r = rr;}};Tnode node[MAX*3];bool aa[MAX];void init(){memset(aa,false,sizeof(aa));    memset(node,0,sizeof(node));}void Updata_len(int t){    node[t].sum = node[t].len() - node[t].sum;}void Swap(int t){    swap(node[t].rw,node[t].rb);    swap(node[t].lw,node[t].lb);    swap(node[t].sw,node[t].sb);}void Updata_wb(int t,int v1,int v2){    node[t].rb = node[t].lb = node[t].sb = v1;    node[t].rw = node[t].lw = node[t].sw = v2;    node[t].sum = v1;}void Updata_cover(int t){    if( node[t].cover == 1 )    {        Updata_wb(L(t), 0, node[L(t)].len());        Updata_wb(R(t), 0, node[R(t)].len());    }    else    {        Updata_wb(L(t), node[L(t)].len(), 0);        Updata_wb(R(t), node[R(t)].len(), 0);    }}void Pushdown_len(int t){    if( node[t].cover > 0 && node[t].len() != 1 )    {        node[R(t)].cover = node[L(t)].cover = node[t].cover;        Updata_cover(t);        node[L(t)].t = node[R(t)].t = 0;    }    node[t].cover = 0;}void Updata_sum(int t){    node[t].lw = node[L(t)].lw + ( node[L(t)].lw == node[L(t)].len() ? node[R(t)].lw : 0 );    node[t].rw = node[R(t)].rw + ( node[R(t)].rw == node[R(t)].len() ? node[L(t)].rw : 0 );    node[t].sw = max(node[R(t)].sw, max(node[L(t)].sw, node[L(t)].rw + node[R(t)].lw));    node[t].lb = node[L(t)].lb + ( node[L(t)].lb == node[L(t)].len() ? node[R(t)].lb : 0 );    node[t].rb = node[R(t)].rb + ( node[R(t)].rb == node[R(t)].len() ? node[L(t)].rb : 0 );    node[t].sb = max(node[R(t)].sb, max(node[L(t)].sb, node[L(t)].rb + node[R(t)].lb));        node[t].sum = node[L(t)].sum + node[R(t)].sum;}             void Pushdown_xor(int t){if( node[t].len() == 1 ){node[t].t = 0;return ;}    if( node[t].t )    {        node[R(t)].t = !node[R(t)].t;        node[L(t)].t = !node[L(t)].t;        Swap(R(t)); Swap(L(t));        Updata_len(R(t)); Updata_len(L(t));        node[t].t = !node[t].t;    }}void Build(int t,int l,int r){    node[t].lr(l,r);    if( node[t].len() == 1 )    {        node[t].sum = node[t].lb = node[t].rb = node[t].sb = aa[l];        node[t].lw = node[t].rw = node[t].sw = 1 - aa[l];        return ;    }    int mid = MID(l,r);    Build(L(t),l,mid);    Build(R(t),mid,r);    Updata_sum(t);}void Updata(int t,int l,int r,int val){    Pushdown_len(t);    Pushdown_xor(t);    if( node[t].in(l,r) )    {if( val != 3 ){        node[t].cover = val;        if( node[t].cover == 1 )            Updata_wb(t, 0, node[t].len());        else            Updata_wb(t, node[t].len(), 0);        return ;}else{        node[t].t = !node[t].t;        Swap(t);        Updata_len(t);        return ;}    }    if( node[t].len() == 1 ) return ;    int mid = MID(node[t].l,node[t].r);    if( l < mid )  Updata(L(t), l, r, val);    if( r > mid )  Updata(R(t), l, r, val);    Updata_sum(t);}int Query_nor(int t,int l,int r){Pushdown_len(t);    Pushdown_xor(t);    if( node[t].in(l,r) ) return node[t].sum;    if( node[t].len() == 1 ) return 0;    int mid = node[t].mid();    int ans = 0;    if( l < mid )  ans += Query_nor(L(t),l,r);    if( r > mid )  ans += Query_nor(R(t),l,r);    Updata_sum(t);    return ans;}int Query_xor(int t,int l,int r){Pushdown_len(t);    Pushdown_xor(t);    if( node[t].in(l,r) ) return node[t].sb;    if( node[t].len() == 1 ) return 0;    int mid = node[t].mid();    int ans = 0;    if( l >= mid )        ans = max(ans,Query_xor(R(t),l,r));    else        if( r <= mid )            ans = max(ans,Query_xor(L(t),l,r));        else        {            ans = max(ans, Query_xor(L(t), l, mid));            ans = max(ans, Query_xor(R(t), mid, r));            int a = ( node[L(t)].rb <= mid - l ? node[L(t)].rb : mid - l);            int b = ( node[R(t)].lb <= r - mid ? node[R(t)].lb : r - mid);            ans = max(ans, a+b);        }    Updata_sum(t);    return ans;}int main(){    int n,m,ncases,a,b,ind;        scanf("%d",&ncases);        while( ncases-- )    {        init();        scanf("%d%d",&n,&m);                for(int i=0; i<n; i++)        {            scanf("%d",&a);            if( a ) aa[i] = 1;}        Build(1,0,n);        while( m-- )        {            scanf("%d%d%d",&ind,&a,&b);                        if( ind == 0 ) Updata(1,a,b+1,1);                 if( ind == 1 ) Updata(1,a,b+1,2);            if( ind == 2 ) Updata(1,a,b+1,3);            if( ind == 3 )            {                int ans = Query_nor(1,a,b+1);                printf("%d\n",ans);            }            if( ind == 4 )            {                int ans = Query_xor(1,a,b+1);                printf("%d\n",ans);            }        }    }return 0;}


原创粉丝点击