poj 2777 Count Color(线段树区间修改)

题目链接:http://poj.org/problem?id=2777

题目意思:就是问你在询问的区间里有几种不同的颜色

思路:这题和一般的区间修改差不多,但是唯一不同的就是我们要怎么计算有种颜色,所以这时候我们就需要把延时标记赋予不同的意义,当某段区间有多种颜色时就赋值为-1,当为一种颜色时就把它赋值为这个颜色的号数。这儿我们要怎么统计询问区间不同的颜色数叻,为了不重复计算同一种颜色,那么我们就需要用一个数组来标记计算过的颜色,当我们下次遇到时就不需要再次计算了。。。。

代码核心处就在计数那儿。。。。其它部分都是模板。。。。。。

code:

<span style="font-size:18px;">#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define L(u) u<<1
#define R(u) u<<1|1
using namespace std;

const int MAXN=100100;
bool vis[35];
int cnt;

struct Node
{
    int l,r;
    int color;
}node[MAXN*4];

void build(int u,int l,int r)          //建树
{
    node[u].l=l;
    node[u].r=r;
    node[u].color=1;
    if(l==r)
    {
        return ;
    }
    int m=(l+r)/2;
    build(L(u),l,m);
    build(R(u),m+1,r);
}

void pushdown(int u)
{
    if(node[u].color>0)
    {
        node[L(u)].color=node[R(u)].color=node[u].color;
    }
}

void pushup(int u)
{
    if(node[L(u)].color==node[R(u)].color)
    {
        node[u].color=node[L(u)].color;
    }
    else
    {
        node[u].color=-1;
    }
}

void update(int l,int r,int v,int u)
{
    if(l<=node[u].l&&node[u].r<=r)
    {
        node[u].color=v;
        return;
    }
    pushdown(u);
    int m=(node[u].l+node[u].r)/2;
    //if(l<=m) update(l,r,v,L(u));
    //if(m<r)  update(l,r,v,R(u));
    if(r<=m) update(l,r,v,L(u));
    else if(l>m) update(l,r,v,R(u));
    else
    {
        update(l,m,v,L(u));
        update(m+1,r,v,R(u));
    }
    pushup(u);
}

void query(int l,int r,int u)
{
    if(node[u].color>0)          //为同一种颜色
    {
        if(vis[node[u].color]==false)      //这种颜色没有计算过
        {
            cnt++;
        }
        vis[node[u].color]=true;           //标记为计算过的
        return ;
    }

    int m=(node[u].l+node[u].r)/2;
    //if(l<=m) query(l,r,L(u));
    //if(m<r)  query(l,r,R(u));
    if(r<=m) query(l,r,L(u));
    else if(l>m) query(l,r,R(u));
    else
    {
        query(l,m,L(u));
        query(m+1,r,R(u));
    }
}

int main()
{
    int n,t,q;
    while(scanf("%d%d%d",&n,&t,&q)==3)
    {
        build(1,1,n);
        while(q--)
        {
            char str[10];
            scanf("%s",str);
            if(str[0]=='C')
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                update(x,y,z,1);
            }
            else
            {
                int x,y;
                scanf("%d%d",&x,&y);
                memset(vis,0,sizeof(vis));
                cnt=0;
                query(x,y,1);
                printf("%d\n",cnt);
            }
        }
    }
    return 0;
}
</span>

poj 2777 Count Color(线段树区间修改),布布扣,bubuko.com

时间: 2024-10-06 07:09:55

poj 2777 Count Color(线段树区间修改)的相关文章

POJ 2777 Count Color(线段树)

题目地址:POJ 2777 我去..延迟标记写错了.标记到了叶子节点上....这根本就没延迟嘛...怪不得一直TLE... 这题就是利用二进制来标记颜色的种类.然后利用或|这个符号来统计每个区间不同颜色种数. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h

POJ 2777 Count Color (线段树+位运算)

题意很简单了,对一个区间有两种操作: 1. "C A B C" Color the board from segment A to segment B with color C. //A~B涂上颜色C 2. "P A B" Output the number of different colors painted between segment A and segment B (including). //输出A~B间颜色的种类数 题目链接:http://poj.o

POJ 2777 count color(线段树,lazy标记)

这里有一个思想:我们在更新的时候不必要更新到叶子节点,只要更新到当前区间包含线段树区间即可. 设计一个标志位,更新到此. A Simple Problem with Integers 也是一个类似的题目 设计两个函数 push_down 将结点信息传递到下层节点(inc, sub,) push_up      将下层节点信息反馈到上层(max,min,count) #include <map> #include <set> #include <queue> #inclu

poj 2777 Count Color(线段树、状态压缩、位运算)

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 38921   Accepted: 11696 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.

POJ 2777 Count Color (线段树成段更新+二进制思维)

题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种. 很明显的线段树成段更新,但是查询却不好弄.经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,....假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6).那我们就把

poj 2777 count color 线段树

Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a positive integer, so we can evenly d

POJ2777 Count Color 线段树区间更新

题目描述: 长度为L个单位的画板,有T种不同的颜料,现要求按序做O个操作,操作分两种: 1."C A B C",即将A到B之间的区域涂上颜色C 2."P A B",查询[A,B]区域内出现的颜色种类 出现操作2时,请输出答案 PS:初始状态下画板颜色为1 一开始没有想那么好,用int整型位移来代替颜色,还是使用了最传统的bool color[来记录,可是不知道错在了哪里, #include<iostream> #include<cstdio>

POJ P2777 Count Color——线段树状态压缩

Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a positive integer, so we can evenly d

Count Color (线段树区间染色?二进制状态压缩)

题目链接:https://vjudge.net/problem/POJ-2777 题意: 有L个画板,30种颜色,o个操作:P a b :询问a-b 种有多少种颜色不同的,C  a b c:把a-b全部涂成c的颜色(覆盖掉) 1 #include <stdio.h> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #in