poj2777

开始不会做,看了大牛的题解, 好神奇说, 把线椴树树和二进制状态联系起来, col用来做延迟标记 num表示区间状态 有几个1就是有几个不同的颜色

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define MAXN 111111


int col[MAXN << 2];
int num[MAXN << 2];

void pushdown( int  rt)
{
    if(col[rt])
    {
        col[rt << 1] = col[rt<<1|1] = col[rt];
        num[rt << 1] = num[rt<<1|1] = 1 <<(col[rt] - 1);
        col[rt] = 0;
    }
}

void pushup( int rt)
{
    num[rt] = num[rt<<1] | num[rt<<1|1];
    col[rt] = 0;
}

void build(int l, int r, int rt)
{
    col[rt] = 0;
    num[rt] = 1;
    if( l == r)
        return ;
    int m = ( l + r) >> 1;
    build(lson);
    build(rson);
    return ;
}

void update(int L, int R, int val,int l, int r, int rt)
{
    if(L <= l && r <= R)
    {
        col[rt] = val;
        num[rt] = 1 << (val - 1) ;
        return ;
    }
    pushdown(rt);
    int m = (l + r) >> 1;
    if(L <= m) update(L , R, val, lson);
    if(m < R) update(L, R, val, rson);
    pushup(rt);
}

int cal(int L, int R, int l, int r, int rt)
{
    if(L <= l && r <= R)
    {
        return num[rt];
    }
    pushdown(rt);
    int m = (l + r) >> 1, res = 0;
    if(L <= m) res |= cal(L, R, lson);
    if( m < R) res |= cal(L, R, rson);
    return res;
}

int solve( int res)
{
    int ans = 0;
    while(res)
    {
        if(res & 1)
         ans++;
         res >>= 1;
    }
    return ans;
}
int main()
{
   int n, l, t, o, ll, rr, c;
   char s[5];
   int a = 1 << 30;
   while(scanf("%d%d%d",&l, &t, &o ) != EOF)
   {

       build(1, l, 1);
       for( int i = 0; i < o; i ++)
       {
           scanf("%s",s);
           if(s[0] == 'C')
           {
               scanf("%d %d %d",&ll, &rr, &c);
               if( ll > rr)
                swap(ll ,rr);
               update(ll, rr, c, 1, l, 1);
           }
           else
           {
               scanf("%d %d",&ll, &rr);
               if( ll > rr)
                swap(ll, rr);
               int tmp = cal(ll ,rr, 1, l ,1);
               printf("%d\n",solve(tmp));
           }
       }
   }
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值