HDOJ 题目3397 Sequence operation(线段树区间覆盖异或合并)

来源:互联网 发布:夜神模拟器for mac 编辑:程序博客网 时间:2024/06/05 14:21

Sequence operation

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7203    Accepted Submission(s): 2153


Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
 

Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
 

Output
For each output operation , output the result.
 

Sample Input
110 100 0 0 1 1 0 1 0 1 11 0 23 0 52 2 24 0 40 3 62 3 74 2 81 0 50 5 63 3 9
 

Sample Output
5265
 

Author
lxhgww&&shǎ崽
 

Source
HDOJ Monthly Contest – 2010.05.01
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  1828 1542 2871 1255 3333 
这么多操作结合起来真是恶心啊,0把区间赋值0,1把区间都赋值成1,2区间异或,3查询区间1的个数,4查询区间连续的1的长度
为何我是如此的弱啊大哭

ac代码
#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>#define max(a,b) (a>b?a:b)#define min(a,b) (a>b?b:a)using namespace std;#define maxn 100010struct s{    int ml0,mr0,mx0;    int ml1,mr1,mx1;    int sum;    int cover,Xor;}node[maxn<<2];void pushup(int tr,int m){    node[tr].ml0=node[tr<<1].ml0;    node[tr].ml1=node[tr<<1].ml1;    node[tr].mr0=node[tr<<1|1].mr0;    node[tr].mr1=node[tr<<1|1].mr1;    if(node[tr<<1].ml0==(m-(m>>1)))        node[tr].ml0+=node[tr<<1|1].ml0;    if(node[tr<<1|1].mr0==(m>>1))        node[tr].mr0+=node[tr<<1].mr0;    node[tr].mx0=max(node[tr<<1].mx0,node[tr<<1|1].mx0);    node[tr].mx0=max(node[tr].mx0,node[tr<<1].mr0+node[tr<<1|1].ml0);        if(node[tr<<1].ml1==(m-(m>>1)))        node[tr].ml1+=node[tr<<1|1].ml1;    if(node[tr<<1|1].mr1==(m>>1))        node[tr].mr1+=node[tr<<1].mr1;    node[tr].mx1=max(node[tr<<1].mx1,node[tr<<1|1].mx1);    node[tr].mx1=max(node[tr].mx1,node[tr<<1].mr1+node[tr<<1|1].ml1);        node[tr].sum=node[tr<<1].sum+node[tr<<1|1].sum;}void fxor(int tr,int m){        swap(node[tr].ml0,node[tr].ml1);        swap(node[tr].mr0,node[tr].mr1);        swap(node[tr].mx0,node[tr].mx1);        node[tr].sum=m-node[tr].sum;}void build(int l,int r,int tr){    node[tr].cover=-1;    node[tr].Xor=0;    if(l==r)    {        int x;        scanf("%d",&x);        node[tr].ml0=node[tr].mr0=node[tr].mx0=(x==0);        node[tr].ml1=node[tr].mr1=node[tr].mx1=(x==1);        node[tr].cover=x;        node[tr].sum=x;        return;    }    int mid=(l+r)>>1;    build(l,mid,tr<<1);    build(mid+1,r,tr<<1|1);    pushup(tr,r-l+1);}void pushdown(int tr,int m){    if(m==1)        return;    if(node[tr].cover!=-1)    {        node[tr<<1].cover=node[tr<<1|1].cover=node[tr].cover;        node[tr<<1].Xor=node[tr<<1|1].Xor=0;        if(node[tr].cover)        {            node[tr<<1].ml1=node[tr<<1].mr1=node[tr<<1].mx1=(m-(m>>1));            node[tr<<1].ml0=node[tr<<1].mr0=node[tr<<1].mx0=0;            node[tr<<1].sum=(m-(m>>1));            node[tr<<1|1].ml1=node[tr<<1|1].mr1=node[tr<<1|1].mx1=(m>>1);            node[tr<<1|1].ml0=node[tr<<1|1].mr0=node[tr<<1|1].mx0=0;            node[tr<<1|1].sum=(m>>1);        }        else        {            node[tr<<1].ml1=node[tr<<1].mr1=node[tr<<1].mx1=0;            node[tr<<1].ml0=node[tr<<1].mr0=node[tr<<1].mx0=(m-(m>>1));            node[tr<<1].sum=0;            node[tr<<1|1].ml1=node[tr<<1|1].mr1=node[tr<<1|1].mx1=0;            node[tr<<1|1].ml0=node[tr<<1|1].mr0=node[tr<<1|1].mx0=(m>>1);            node[tr<<1|1].sum=0;        }        node[tr].cover=-1;    }    if(node[tr].Xor)    {        node[tr<<1].Xor^=1;        node[tr<<1|1].Xor^=1;        fxor(tr<<1,m-(m>>1));        fxor(tr<<1|1,m>>1);        node[tr].Xor=0;    }}void update(int L,int R,int l,int r,int tr,int op){    pushdown(tr,r-l+1);//先向下跟新啊。。    if(L<=l&&r<=R)    {        if(op==2)        {            node[tr].Xor=1;            fxor(tr,r-l+1);        }        else        {            int m=(r-l)+1;            node[tr].cover=op;            if(op)            {                node[tr].ml1=node[tr].mr1=node[tr].mx1=m;                node[tr].ml0=node[tr].mr0=node[tr].mx0=0;                node[tr].sum=m;            }            else            {                node[tr].ml1=node[tr].mr1=node[tr].mx1=0;                node[tr].ml0=node[tr].mr0=node[tr].mx0=m;                node[tr].sum=0;            }        }        return;    }    int mid=(l+r)>>1;    if(L<=mid)        update(L,R,l,mid,tr<<1,op);    if(R>mid)        update(L,R,mid+1,r,tr<<1|1,op);    pushup(tr,r-l+1);}int query_sum(int L,int R,int l,int r,int tr){    if(L<=l&&r<=R)    {        return node[tr].sum;    }    pushdown(tr,r-l+1);    int mid=(l+r)>>1;    int ans1=0;    int ans2=0;    if(L<=mid)        ans1=query_sum(L,R,l,mid,tr<<1);    if(R>mid)        ans2=query_sum(L,R,mid+1,r,tr<<1|1);//    pushup(tr,r-l+1);    return ans1+ans2;}int query_max1(int L,int R,int l,int r,int tr){    if(L<=l&&r<=R)    {        return node[tr].mx1;    }    pushdown(tr,r-l+1);    int mid=(l+r)>>1;    int ans=0;    if(R<=mid)        ans=query_max1(L,R,l,mid,tr<<1);    else        if(L>mid)            ans=query_max1(L,R,mid+1,r,tr<<1|1);        else        {            int ans1=query_max1(L,mid,l,mid,tr<<1);            int ans2=query_max1(mid+1,R,mid+1,r,tr<<1|1);            int ans3=min(node[tr<<1].mr1,mid-L+1)+min(node[tr<<1|1].ml1,R-(mid+1)+1);            ans=max(ans1,max(ans2,ans3));        }    //    pushup(tr,r-l+1);    return ans;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n,m;        scanf("%d%d",&n,&m);        build(1,n,1);        while(m--)        {            int op,x,y;            scanf("%d%d%d",&op,&x,&y);            x++;            y++;            if(op<3)                update(x,y,1,n,1,op);            else            {                if(op==3)                {                    printf("%d\n",query_sum(x,y,1,n,1));                }                else                {                    printf("%d\n",query_max1(x,y,1,n,1));                }            }        }    }} 


 
0 0