zoukankan      html  css  js  c++  java
  • hdu 3397 线段树双标记

    Sequence operation

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


    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
    1
    10 10
    0 0 0 1 1 0 1 0 1 1
    1 0 2
    3 0 5
    2 2 2
    4 0 4
    0 3 6
    2 3 7
    4 2 8
    1 0 5
    0 5 6
    3 3 9


    Sample Output

    5
    2
    6
    5



    /*
    hdu 3397 线段树双标记
    
    给你5个操作:
    0:将区间[a,b]之间的数全部置为0
    1:将区间[a,b]之间的数全部置为1
    2:将区间[a,b]之间的 1->0  0->1
    3:求区间[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
    ",query2(1,x,y));
                else
                    printf("%d
    ",query1(1,x,y));
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/Przz/p/5409589.html
Copyright © 2011-2022 走看看