poj 2777

题意:两个操作:c l r x   l到r之间的颜色变成x

q l r      询问l到r有多少种颜色

思路:记一个整数表示哪种颜色是否取了

这里真的是煞笔了,看到这一题第一直觉是异或,但是A^A=0,相同的肿么办..然后搜题解....反应了一个下午,发现有按位或这样神气的存在

1|1=1

1|0=1

0|1=1

0|0=0

代码

#include "stdio.h"
#include "string.h"
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#include "algorithm"
#define MAX 100010
using namespace std;
int sum[MAX<<2],col[MAX<<2];
void pushup(int rt)
{
    sum[rt]=(sum[rt<<1]|sum[rt<<1|1]);
}
void pushdown(int rt)
{
    if(col[rt])
    {
        col[rt<<1]=col[rt<<1|1]=col[rt];
        sum[rt<<1]=sum[rt<<1|1]=1<<(col[rt]-1);
        col[rt]=0;
    }
}
void build(int l,int r,int rt)
{
    col[rt]=0;
    if(l==r)
    {
        sum[rt]=1;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(l>=L&&r<=R)
    {
          col[rt]=c;
          sum[rt]=1<<(c-1);
          return;
    }
    pushdown(rt);
    int m=(l+r)>>1;
    if(L<=m)
        update(L,R,c,lson);
    if(R>m)
        update(L,R,c,rson);
    pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if(l>=L&&r<=R)
    {
          return sum[rt];
    }
    pushdown(rt);
    int ans=0;
    int m=(l+r)>>1;
    if(L<=m)
          ans=(ans|query(L,R,lson));
    if(R>m)
          ans=(ans|query(L,R,rson));
    return ans;
}
int main()
{
    int n,l,r,col,x;
    int q;
    char s[10];
    while(scanf("%d%d%d",&n,&col,&q)==3)
    {
        build(1,n,1);
        while(q--)
        {
            scanf("%s",s);
            if(s[0]==‘C‘)
            {
                scanf("%d%d%d",&l,&r,&x);
                if(l>r)
                    l^=r^=l^=r;
                update(l,r,x,1,n,1);
            }
            else
           {
               scanf("%d%d",&l,&r);
               if(l>r)
                    l^=r^=l^=r;
               int temp=query(l,r,1,n,1);
               int ans=0;
               while(temp)
               {
                   if(temp&1)
                        ans++;
                   temp/=2;
               }
               printf("%d\n",ans);
           }
        }
    }
    return 0;
}

时间: 2024-08-29 19:52:19

poj 2777的相关文章

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

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

题目链接:http://poj.org/problem?id=2777 题目意思:就是问你在询问的区间里有几种不同的颜色 思路:这题和一般的区间修改差不多,但是唯一不同的就是我们要怎么计算有种颜色,所以这时候我们就需要把延时标记赋予不同的意义,当某段区间有多种颜色时就赋值为-1,当为一种颜色时就把它赋值为这个颜色的号数.这儿我们要怎么统计询问区间不同的颜色数叻,为了不重复计算同一种颜色,那么我们就需要用一个数组来标记计算过的颜色,当我们下次遇到时就不需要再次计算了.... 代码核心处就在计数那儿

POJ 2777 Count Color

C - Count Color Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2777 Appoint description:  System Crawler  (2015-07-22) Description Chosen Problem Solving and Program design as an optional cours

poj 2777 线段树的区间更新

Count Color Time Limit: 1000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Chosen Problem Solving and Program design as an optional course, you are required to solve al

poj 2777 Count Color【线段树段更新】

题目:poj 2777 Count Color 题意:给出一段1 * n 的栅栏,有两种操作,第一种:把 l -- r 全部染成同一颜色t,第二种,查询 l---r 一共有多少种颜色. 分类:线段树 分析:我们可以给每个节点加一个标记,标记当前节点是否只有一种颜色,然后对只有一种颜色的节点如果要染色的话,那么他会变成几种颜色的,这时候记得向下更新一次就好,统计的时候统计节点有单个颜色的颜色就好. 代码: #include <cstdio> #include <cstring> #i

POJ 2777 Count Color(线段树)

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

POJ 2777 &amp;&amp; ZOJ 1610 &amp;&amp;HDU 1698 --线段树--区间更新

直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 -- 区间更新的话 分为 增减 或者 修改 主要就是个 laze 标记 就是延迟更新 对于区间更新的写法 一般是有2种 其一 仔细划分到每个细小的区间    另一 粗略划分 反正 ==我的代码里会给出2种写法 看自己喜好 hdu 1 //线段树 成段更新 ---> 替换 根结点的查询 2 3 #i

POJ 2777 Count Color(线段树)

POJ 2777 Count Color 题目链接 就一个线段树,颜色二进制表示就可以,成段更新成段查询延迟操作 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) const int N = 100005; struct No

poj 2777(线段树的节点更新策略)

1 /* 2 之前的思想是用回溯的方式进行颜色的更新的!如果用回溯的方法的话,就是将每一个节点的颜色都要更新 3 通过子节点的颜色情况来判断父节点的颜色情况 !这就是TLE的原因! 4 5 后来想一想没有必要 !加入[a, b] 区间有p管辖,那么tree[p]的颜色值就是[a, b]所有点的颜色值! 6 如果[a,b]的子区间[c,d]没被跟新,那么tree[p]也是[c,d]的值! 7 否则,在更新[c,d]区间的时候,一定会经过 p 点!然后由上到下更新p<<1 和 p<<1

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