hdu 3397 线段树双标记

来源:互联网 发布:smartdraw mac 破解版 编辑:程序博客网 时间:2024/05/29 15:45

Sequence operation

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


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


/*hdu 3397 线段树双标记给你5个操作:0:将区间[a,b]之间的数全部置为01:将区间[a,b]之间的数全部置为12:将区间[a,b]之间的 1->0  0->13:求区间[a,b]之间1的个数4:求区间[a,b]之间1的最长连续长度先设定ls1,rs1,ms1,num1  ls0,rs0,ms0,num0分别记录1,0的情况然后是rev和same标记,区间合并这些到是没什么问题,主要是在标记下放最开始没有注意标记之间的互相影响的问题,假设[a,b]上即有rev又有same我们应该怎么处理之.所以最开始WR了几次,然后想只记录same标记,当进行rev操作时  要么更新到点,要么遇到same对标记进行修改,尝试了很久,一直TLE然后考虑same和rev之间的关系,假设same在[a,b]上遇到一个rev,那么把该区间上原先有的rev删除.如果rev在[a,b]上遇见一个same标记,那么只需要对same进行修改即可,否则将0 1的数据进行交换hhh-2016-04-01 21:52:19*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <functional>using namespace std;#define lson  (i<<1)#define rson  ((i<<1)|1)typedef long long ll;const int maxn = 200050;struct node{    int l,r;    int same,rev;    int ls1,rs1,ms1;    int ls0,rs0,ms0;    int num1,num0;    int mid()    {        return (l+r)>>1;    }    int len()    {        return (r-l+1);    }} tree[maxn<<2];void push_up(int i){    tree[i].ls0 = tree[lson].ls0,tree[i].ls1 = tree[lson].ls1;    tree[i].rs0 = tree[rson].rs0,tree[i].rs1 = tree[rson].rs1;    tree[i].num1 = tree[lson].num1 + tree[rson].num1;    tree[i].num0 = tree[lson].num0 + tree[rson].num0;    if(tree[i].ls1 == tree[lson].len() )        tree[i].ls1 += tree[rson].ls1;    if(tree[i].ls0 == tree[lson].len() )        tree[i].ls0 += tree[rson].ls0;    if(tree[i].rs1 == tree[rson].len() )        tree[i].rs1 += tree[lson].rs1;    if(tree[i].rs0 == tree[rson].len() )        tree[i].rs0 += tree[lson].rs0;    tree[i].ms1 = max(tree[lson].ms1,tree[rson].ms1);    tree[i].ms0 = max(tree[lson].ms0,tree[rson].ms0);    tree[i].ms1 = max(tree[i].ms1,tree[lson].rs1+tree[rson].ls1);    tree[i].ms0 = max(tree[i].ms0,tree[lson].rs0+tree[rson].ls0);}void ini1(int i,int val){    tree[i].num1=tree[i].ls1 = tree[i].rs1 = tree[i].ms1 = val;}void ini0(int i,int val){    tree[i].num0=tree[i].ls0 = tree[i].rs0 = tree[i].ms0 = val;}void build(int i,int l,int r){    tree[i].l = l,tree[i].r = r;    ini1(i,0),ini0(i,0);    tree[i].same = -1;    tree[i].rev = 0;    if(l == r)    {        int x;        scanf("%d",&x);        if(x)            ini1(i,1);        else            ini0(i,1);        return ;    }    int mid = tree[i].mid();    build(lson,l,mid);    build(rson,mid+1,r);    push_up(i);}void exchange(int i){    swap(tree[i].ls1,tree[i].ls0);    swap(tree[i].rs1,tree[i].rs0);    swap(tree[i].ms0,tree[i].ms1);    swap(tree[i].num0,tree[i].num1);}void solve(int i){    tree[i].same ^= 1;    if(tree[i].same)    {        ini1(i,tree[i].len());        ini0(i,0);    }    else    {        ini1(i,0);        ini0(i,tree[i].len());    }}void push_down(int i){    if(tree[i].same != -1)    {        tree[lson].rev = tree[rson].rev = 0;        tree[lson].same = tree[i].same;        tree[rson].same = tree[i].same;        if(tree[i].same)        {            ini1(lson,tree[lson].len()),ini0(lson,0);            ini1(rson,tree[rson].len()),ini0(rson,0);        }        else        {            ini1(lson,0),ini1(rson,0);            ini0(lson,tree[lson].len()),ini0(rson,tree[rson].len());        }        tree[i].same = -1;    }    if(tree[i].rev)    {        if(tree[lson].same != -1)        {            solve(lson);        }        else        {            tree[lson].rev ^= 1;            exchange(lson);        }        if(tree[rson].same != -1)        {            solve(rson);        }        else        {            tree[rson].rev ^= 1;            exchange(rson);        }        tree[i].rev = 0;    }}void update_same(int i,int l,int r,int va){    if(tree[i].l >= l && tree[i].r <= r )    {        tree[i].rev = 0;        if(va)        {            ini1(i,tree[i].len()),ini0(i,0);        }        else        {            ini1(i,0),ini0(i,tree[i].len());        }        tree[i].same = va;        return;    }    push_down(i);    int mid = tree[i].mid();    if(l <= mid)        update_same(lson,l,r,va);    if(r > mid)        update_same(rson,l,r,va);    push_up(i);}void update_rev(int i,int l,int r){    if(tree[i].l >= l && tree[i].r <= r)    {        if(tree[i].same != -1)        {            solve(i);            return ;        }        tree[i].rev ^= 1;        exchange(i);        return;    }    push_down(i);    int mid = tree[i].mid();    if(l <= mid)        update_rev(lson,l,r);    if(r > mid)        update_rev(rson,l,r);    push_up(i);}int query1(int i,int l,int r){    if(tree[i].l >= l && tree[i].r <= r)    {        return tree[i].ms1;    }    int mid = tree[i].mid();    push_down(i);    if(r <= mid)        return query1(lson,l,r);    else if(l > mid)        return query1(rson,l,r);    else    {        int ans1 = query1(lson,l,mid);        int ans2 = query1(rson,mid+1,r);        return max(max(ans1,ans2),min(tree[lson].rs1,mid-l+1)+min(tree[rson].ls1,r-mid));    }}int query2(int i,int l,int r){    if(l <= tree[i].l && tree[i].r <= r)    {        return tree[i].num1;    }    push_down(i);    int mid = tree[i].mid();    int num = 0;    if(l <= mid)        num += query2(lson,l,r);    if(r > mid)        num += query2(rson,l,r);    return num;}int op;int x,y;int T,n,m;int main(){    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        build(1,0,n-1);        while(m--)        {            scanf("%d",&op);            scanf("%d%d",&x,&y);            if(op == 0)                update_same(1,x,y,0);            else if(op == 1)                update_same(1,x,y,1);            else if(op == 2)                update_rev(1,x,y);            else if(op == 3)                printf("%d\n",query2(1,x,y));            else                printf("%d\n",query1(1,x,y));        }    }    return 0;}


0 0
原创粉丝点击