[PKU] 2777 Count Color -- 线段树

    我是先按常规的方法把每个区间的颜色更新到位,然后在查询的时候,遇到一个颜色就标记在res上(因为最多只有30种颜色,所以可以用位运算来标记状态)。最后计算res的二进制里面有多少个1就行了。

Source Code

Problem: 2777 User: yueashuxia
Memory: 4844K Time: 469MS
Language: C++ Result: Accepted
  • Source Code
  • #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int size = 100001 ;
    
    int res, tot ;
    
    struct xds
    {
    	int a, b ;
    	int lson, rson, info, flag ;
    }tree[size * 3] ;
    
    /*
    void print(int p)
    {
    	printf("a = %d b = %d ", tree[p].a, tree[p].b);
    	printf("info = %d flag = %s/n", tree[p].info, tree[p].flag ? "true":"false");
    }
    */
    
    void build(int a, int b)
    {
    	int now = ++tot ;
    	tree[now].a = a ;
    	tree[now].b = b ;
    	tree[now].info = 0 ;
    	tree[now].flag = 1 ;
    	if(a == b) 
    	{
     		tree[now].lson = tree[now].rson = 0 ;
     		return ;
     	}
    	int mid = (a + b) >> 1 ;
    	tree[now].lson = tot + 1 ;
    	build(a, mid) ;
    	tree[now].rson = tot + 1 ;
    	build(mid + 1, b) ;
    }
    
    void update(int p, int a, int b, int info)
    {
    	//print(p) ;
    	if(a <= tree[p].a && tree[p].b <= b)
    	{
     		tree[p].info = info - 1 ;
     		tree[p].flag = 1 ;
     		return ;
     	}
     	if(tree[p].a == tree[p].b) return ;
     	if(tree[p].flag)
     	{
      		tree[tree[p].lson].info = tree[tree[p].rson].info = tree[p].info ;
      		tree[tree[p].lson].flag = tree[tree[p].rson].flag = 1 ;
      		tree[p].flag = 0 ;
      	}
     	int mid = (tree[p].a + tree[p].b) >> 1 ;
     	if(a <= mid) update(tree[p].lson, a, b, info) ;
     	if(b > mid) update(tree[p].rson, a, b, info) ;
    }
    
    void query(int p, int a, int b)
    {
    	//print(p) ;
    	if(tree[p].a == a && tree[p].b == b)
    	{
     		if(tree[p].flag) 
     		{
       			res |= (1<<tree[p].info) ;
       			//printf("res = %d/n", res);
       			return ;
       		}
     	}
     	if(tree[p].flag)
     	{
      		tree[tree[p].lson].info = tree[tree[p].rson].info = tree[p].info ;
      		tree[tree[p].lson].flag = tree[tree[p].rson].flag = 1 ;
      		//tree[p].flag = 0 ;
      	}
     	if(tree[p].a == tree[p].b) return ;
     	int mid = (tree[p].a + tree[p].b) >> 1 ;
     	if(b <= mid) query(tree[p].lson, a, b) ;
     	else if(a > mid) query(tree[p].rson, a, b) ;
     	else query(tree[p].lson, a, mid), query(tree[p].rson, mid + 1, b) ;
    }
    
    int main (){
        int l, t, o, a, b, c, cnt, i ;
        char op[2] ;
        while(scanf("%d%d%d", &l, &t, &o) != EOF)
        {
        	tot = 0 ;
        	build(1, l) ;
        	while(o --)
        	{
         		scanf("%s%d%d", op, &a, &b);
         		if(a > b) swap(a, b) ;
         		if(op[0] == 'P')
         		{
           			res = cnt = 0 ;
           			query(1, a, b) ;
           			while(res)
           			{
              			cnt ++ ;
              			res = res & (res - 1) ;
              		}
              		printf("%d/n", cnt);
           		}
           		else 
           		{
             		scanf("%d", &c);
             		update(1, a, b, c) ;
             	}
          	}
        }
        //system ("pause") ;
        return 0 ;
    }
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值