码迷,mamicode.com
首页 > 其他好文 > 详细

Sequence operation

时间:2015-07-26 14:16:30      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:hdu   3397   sequence-o   线段树   

//0 a b 将[a,b]区间的所有数变为0
//1 a b 将[a,b]区间的所有数都变为1
//2 a b 将[a,b]区间的所有数01,10
//3 a b 问[a,b]区间的1的个数
//4 a b 问[a,b]区间最长的连续1的子段长度
//维护ma_l[2] , ma_r[2] , ma[2] ,sum[2]分别为区间左边,右边,最大的连续10,,区间10的个数
//lazy  为0,1,2分别表示三个操作
//lazy push_down的时候需要注意其子节点的lazy是初始状态-1#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 100010 ;
#define left v<<1
#define right v<<1|1
struct node
{
    int l ; int r ;int  lazy ;
    int ma_l[2] , ma_r[2] , ma[2] , sum[2] ;
}tree[maxn<<2] ;
int h[maxn] ;
void push_down(int v)
{
    if(tree[v].l == tree[v].r)
    return ;
    if(tree[v].lazy == 2)
    {
        if(tree[left].lazy != -1)
        push_down(left);
        swap(tree[left].ma_l[0] , tree[left].ma_l[1]) ;
        swap(tree[left].ma_r[0] , tree[left].ma_r[1]) ;
        swap(tree[left].ma[0] ,  tree[left].ma[1]) ;
        swap(tree[left].sum[0] , tree[left].sum[1]) ;
        tree[left].lazy = tree[v].lazy ;
        if(tree[right].lazy != -1)
        push_down(right) ;
        swap(tree[right].ma_l[0] , tree[right].ma_l[1]) ;
        swap(tree[right].ma_r[0] , tree[right].ma_r[1]) ;
        swap(tree[right].ma[0] , tree[right].ma[1]);
        swap(tree[right].sum[0] , tree[right].sum[1]) ;
        tree[right].lazy = tree[v].lazy ;
    }
    else if(tree[v].lazy != -1)
    {
        int t = tree[v].lazy ;
        tree[left].ma_l[t] = tree[left].ma_r[t] = tree[left].ma[t] = tree[left].sum[t] = (tree[left].r - tree[left].l + 1) ;
        tree[left].ma_l[!t] = tree[left].ma_r[!t] = tree[left].ma[!t] = tree[left].sum[!t] = 0 ;
        tree[right].ma_l[t] = tree[right].ma_r[t] = tree[right].ma[t] = tree[right].sum[t] = (tree[right].r - tree[right].l + 1) ;
        tree[right].ma_l[!t] = tree[right].ma_r[!t] = tree[right].ma[!t] = tree[right].sum[!t] = 0 ;
        tree[left].lazy = tree[right].lazy = tree[v].lazy ;
    }
    tree[v].lazy = -1 ;
}
void push_up(int v)
{
    for(int i = 0;i < 2;i++)
    {
        tree[v].ma_l[i] = tree[left].ma_l[i] ;
        tree[v].ma_r[i] = tree[right].ma_r[i] ;
        tree[v].ma[i] = max(max(tree[left].ma[i] , tree[right].ma[i]), tree[left].ma_r[i] + tree[right].ma_l[i]) ;
        if(tree[v].ma_l[i] == tree[left].r - tree[left].l + 1)
        tree[v].ma_l[i] += tree[right].ma_l[i] ;
        if(tree[v].ma_r[i] == tree[right].r - tree[right].l + 1)
        tree[v].ma_r[i] += tree[left].ma_r[i] ;
        tree[v].sum[i] = tree[left].sum[i]  + tree[right].sum[i] ;
    }
}
void build(int l , int r , int v)
{
    tree[v].l = l ;
    tree[v].r = r;
    tree[v].lazy  = -1 ;
    if(l == r)
    {
        tree[v].ma[h[l]] = tree[v].ma_l[h[l]] = tree[v].ma_r[h[l]] = tree[v].sum[h[l]] = 1;
        tree[v].ma[!h[l]] = tree[v].ma_l[!h[l]] = tree[v].ma_r[!h[l]] = tree[v].sum[!h[l]] = 0;
        return  ;
    }
    int mid = (l + r) >> 1 ;
    build(l , mid , left) ;
    build(mid+1 , r , right) ;
    push_up(v) ;
}
int  query(int l , int r , int v ,  int op)
{

    if(l <= tree[v].l && tree[v].r <= r)
    {
        if(op == 3)
        return tree[v].sum[1];
        else return tree[v].ma[1] ;
    }
    push_down(v) ;
    int mid = (tree[v].l + tree[v].r) >> 1 ;
    int ans_1 = 0, ans_2 = 0 , ans = 0;
    if(l <= mid)ans_1 = query(l , r , left , op) ;
    if(r > mid)ans_2 = query(l , r , right, op) ;
    if(op == 3)return ans_1 + ans_2 ;
    if(mid >=l && mid < r)
    ans = min(tree[left].ma_r[1] , tree[left].r - l + 1) + min(tree[right].ma_l[1] , r - tree[right].l + 1) ;
    return max(max(ans_1  , ans_2) , ans) ;
}
void update(int l , int r , int v , int op)
{
    push_down(v) ;
    if(l <= tree[v].l && tree[v].r <= r)
    {
        if(op == 2)
        {
            swap(tree[v].ma_l[0] , tree[v].ma_l[1]) ;
            swap(tree[v].ma_r[0] , tree[v].ma_r[1]) ;
            swap(tree[v].ma[0]  , tree[v].ma[1]) ;
            swap(tree[v].sum[0] , tree[v].sum[1]) ;
            tree[v].lazy = op ;
        }
        else
        {
            for(int i = 0;i < 2;i++)
            tree[v].ma_l[i] = tree[v].ma[i] = tree[v].ma_r[i] = tree[v].sum[i] = (tree[v].r - tree[v].l + 1)*(op == i ? 1 : 0) ;
            tree[v].lazy = op ;
        }
        return ;
    }
    int mid = (tree[v].l  + tree[v].r) >> 1 ;
    if(l <= mid)update(l , r , left ,op) ;
    if((r > mid))update(l , r , right ,op) ;
    push_up(v) ;
}
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
    int T ;
    int n , m ;
    scanf("%d" , &T) ;
    while(T--)
    {
        scanf("%d%d" ,&n , &m) ;
        for(int i = 1;i <= n;i++)
        scanf("%d" , &h[i]) ;
        build(1 , n , 1) ;
        int op , a , b ;
        while(m--)
        {
            scanf("%d%d%d" ,&op , &a , &b) ;
            if(op < 3)
            update(a + 1, b + 1 , 1 , op) ;
            else printf("%d\n" , query(a + 1, b + 1 , 1 , op)) ;
        }
    }
    return  0;
}































版权声明:本文为博主原创文章,未经博主允许不得转载。

Sequence operation

标签:hdu   3397   sequence-o   线段树   

原文地址:http://blog.csdn.net/cq_pf/article/details/47067401

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!