poj 2777 -- Count Color ( 线段树 )

WA了两天后终于A掉了,好开心, 按自己的理解实现的lazy ,实现上可能麻烦点 , 效率也略低 ,等看看别人代码学习下


# include <cstdio>
# include <iostream>
# include <set>
# include <map>
# include <vector>
# include <list>
# include <queue>
# include <stack>
# include <cstring>
# include <string>
# include <cstdlib>
# include <cmath>
# include <algorithm>

using namespace std ;

const int maxn = 110000 ;
struct Tree
{
    int flag ;
    bool hash [ 31 ] ;
    int sum ;
} tree [ maxn * 4 ] ;
bool tm [ 31 ] ;
int t ;

void pushup ( int pos )
{
    for ( int i = 1 ; i <= t ; i ++ )
    {
        tree [ pos ] . hash [ i ] = ( tree [ pos * 2 ] . hash [ i ] || tree [ pos * 2 + 1 ] . hash [ i ] ) ;
    }
}

void pushdown ( int pos )
{
    tree [ pos * 2 ] . flag = 1 ;
    tree [ pos * 2 + 1 ] . flag = 1 ;
    for ( int i = 1 ; i <= t ; i ++ )
    {
        tree [ pos * 2 ] . hash [ i ] = tree [ pos * 2 + 1 ] . hash [ i ] = tree [ pos ] . hash [ i ] ;
    }
}

void build ( int l , int r , int pos )
{
    tree [ pos ] . sum = 1 ;
    tree [ pos ] . hash [ 1 ] = 1 ;
    if ( l == r )
        return ;
    int m = ( l + r ) / 2 ;
    build ( l , m , pos * 2 ) ;
    build ( m + 1 , r , pos * 2 + 1 ) ;
}

void update ( int l , int r , int pos , int L , int R , int C )
{
    if ( l >= L && r <= R )
    {
        memset ( tree [ pos ] . hash , 0 , sizeof ( tree [ pos ] . hash ) ) ;
        tree [ pos ] . hash [ C ] = 1 ;
        tree [ pos ] . flag = 1 ;
        return ;
    }
    //cout << l << ' ' << r << ' ' << C << endl ;
    if ( tree [ pos ] . flag )
    {
        tree [ pos ] . flag = 0 ;
        pushdown ( pos ) ;
    }
    int m = ( l + r ) / 2 ;
    if ( m >= L )
        update ( l , m , pos * 2 , L , R , C ) ;
    if ( m + 1 <= R )
        update ( m + 1 , r , pos * 2 + 1 , L , R , C ) ;
    pushup ( pos ) ;
}

void quer ( int l , int r , int pos , int L , int R )
{
    //cout << l << ' ' << r << ' ' ;
    if ( l >= L && r <= R || tree [ pos ] . flag )
    {
        for ( int i = 1 ; i <= t ; i ++ )
        {
            tm [ i ] = ( tm [ i ] || tree [ pos ] . hash [ i ] ) ;
        }
        return ;
    }
    int m = ( l + r ) / 2 ;
    if ( m >= L )
        quer ( l , m , pos * 2 , L , R ) ;
    if ( m + 1 <= R )
        quer ( m + 1 , r , pos * 2 + 1 , L , R ) ;
}

int main ( )
{
    int n , q ;
    while ( ~ scanf ( "%d%d%d" , & n , & t , & q ) )
    {
        memset ( tree , 0 , sizeof ( tree ) ) ;
        getchar ( ) ;
        build ( 1 , n , 1 ) ;
        while ( q -- )
        {
            char c ;
            c = getchar ( ) ;
            if ( c == 'C' )
            {
                int x , y , z ;
                scanf ( "%d%d%d" , & x , & y , & z ) ;
                update ( 1 , n , 1 , min ( x , y ) , max ( x , y ) , z ) ;
            }
            else
            {
                int x , y ;
                scanf ( "%d%d" , & x , & y ) ;
                memset ( tm , 0 , sizeof ( tm ) ) ;
                quer ( 1 , n , 1 , min ( x , y ) , max ( x , y ) ) ;
                int num = 0 ;
                for ( int i = 1 ; i <= t ; i ++ )
                    if ( tm [ i ] )
                    {
                        num ++ ;
                        // cout << i << endl ;
                    }
                printf ( "%d\n" , num ) ;
            }
            getchar ( ) ;
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值