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 #include <set>
  7 #include <map>
  8
  9 #define LL long long
 10 using namespace std;
 11 const int maxn = 100005;
 12
 13 int n,m,q;
 14 char c;
 15 int x,y,z;
 16 int sum;
 17 struct segment_tree{
 18     int l,r,col;
 19     int lazy;
 20 }tree[maxn*4];
 21
 22 void pushup(int nod){
 23     tree[nod].col = tree[nod<<1].col | tree[(nod<<1)+1].col;
 24     return ;
 25 }
 26
 27 void pushdown(int nod){
 28     tree[nod].lazy = 0;
 29     tree[nod<<1].lazy = 1;
 30     tree[(nod<<1)+1].lazy = 1;
 31     tree[nod<<1].col = tree[nod].col;
 32     tree[(nod<<1)+1].col = tree[nod].col;
 33     return ;
 34 }
 35
 36 void build(int nod,int l,int r){
 37     tree[nod].l = l;
 38     tree[nod].r = r;
 39     tree[nod].col = 1; //这个初始化根据具体题目而决定
 40     tree[nod].lazy = 0;
 41     if (l == r)
 42         return ;
 43     int mid = (tree[nod].l + tree[nod].r)>>1;
 44     build(nod<<1,l,mid);
 45     build((nod<<1)+1,mid+1,r);
 46     pushup(nod);
 47 }
 48
 49 void updata(int nod,int l,int r,int val){
 50     if (tree[nod].l == l && tree[nod].r == r){
 51         tree[nod].col = 1<<(val-1);
 52         tree[nod].lazy = 1;
 53         return ;
 54     }
 55     if (tree[nod].col == 1<<(val-1))  // 如果颜色一样,不用更新
 56         return ;
 57     if (tree[nod].lazy)
 58         pushdown(nod);
 59     int mid = (tree[nod].l + tree[nod].r) >> 1;
 60     if (r <= mid){
 61         updata(nod<<1,l,r,val);
 62     }
 63     else if (l>mid){
 64         updata((nod<<1)+1,l,r,val);
 65     }
 66     else {
 67         updata(nod<<1,l,mid,val);
 68         updata((nod<<1)+1,mid+1,r,val);
 69     }
 70     pushup(nod);
 71 }
 72
 73 void querry(int nod,int l,int r){
 74     if (tree[nod].l == l && tree[nod].r == r){
 75         sum |= tree[nod].col;
 76         return ;
 77     }
 78     if (tree[nod].lazy){
 79         pushdown(nod);
 80     }
 81     int mid = (tree[nod].l + tree[nod].r) >> 1;
 82     if (r <= mid){
 83         querry(nod<<1,l,r);
 84     }
 85     else if (l>mid){
 86         querry((nod<<1)+1,l,r);
 87     }
 88     else {
 89         querry(nod<<1,l,mid);
 90         querry((nod<<1)+1,mid+1,r);
 91     }
 92 }
 93
 94 int Ans(int sum){
 95     int ans = 0;
 96     while (sum){
 97         if (sum & 1){
 98             ans++;
 99         }
100         sum = (sum>>1);
101     }
102     return ans;
103 }
104
105
106 int main(){
107     scanf("%d%d%d",&n,&m,&q);
108     build(1,1,n);
109     getchar();
110     for(int i=1;i<=q;i++)
111     {
112         scanf("%s",&c);
113         if(c==‘C‘)
114         {
115             scanf("%d%d%d",&x,&y,&z);
116             if(x>y)swap(x,y);
117             getchar();
118             updata(1,x,y,z);
119         }
120         else
121         {
122             scanf("%d%d",&x,&y);
123             getchar();
124             sum=0;
125             if(x>y)swap(x,y);//x可能>y
126             querry(1,x,y);
127             cout<<Ans(sum)<<endl;;
128         }
129     }
130     return 0;
131 }

原文地址:https://www.cnblogs.com/-Ackerman/p/11381298.html

时间: 2024-12-12 12:18:17

Count Color (线段树区间染色?二进制状态压缩)的相关文章

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 2777 Count Color(线段树)

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

POJ 2528 Mayor&#39;s posters(线段树区间染色+离散化或倒序更新)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59239   Accepted: 17157 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

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

HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)

题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树).当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工作),题目会询问你其中某个人正在做的工作. 解题思路:其实从"一个人分配他的下属做一样的工作"这里就可以看出来了,这相当于让一块区间的人都做一样的事,就是线段树区间染色问题.但不能使用线段树,要先将多叉树铺展开,将节点映射到线段上.把每个人的管理区段找出来(把属于同一个人管的放一起,上司放

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 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

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).那我们就把