C++-POJ2777-Count Color[线段树][lazy标记][区间修改]

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 const int MAXN=1e5+10;
 5 struct node{int l,r,lazy,color;}t[MAXN*4];
 6 int L,R,C,n,m,q;
 7 #define ls t[x].l
 8 #define rs t[x].r
 9 int count(int x){int ans=0;for(;x;x>>=1)if(x&1)ans++;return ans;}
10 void pushdown(int x){if(t[x].lazy)t[ls].lazy=t[rs].lazy=t[ls].color=t[rs].color=t[x].lazy,t[x].lazy=0;}
11 void update(int x){t[x].color=t[ls].color|t[rs].color;}
12 void build(int x,int l,int r){
13     if(l==r){t[x].color=1;return;}
14     int mid=(l+r)>>1;t[x].l=(x<<1),t[x].r=(x<<1|1);
15     build(ls,l,mid),build(rs,mid+1,r),update(x);
16 }
17 void update(int x,int l,int r){
18     if(L<=l&&r<=R){t[x].color=t[x].lazy=1<<(C-1);return;}
19     pushdown(x);int mid=(l+r)>>1;
20     if(L<=mid)update(ls,l,mid);
21     if(R>mid)update(rs,mid+1,r);
22     update(x);
23 }
24 int query(int x,int l,int r){
25     if(L<=l&&r<=R)return t[x].color;
26     pushdown(x);int mid=(l+r)>>1,ans=0;
27     if(L<=mid)ans|=query(ls,l,mid);
28     if(R>mid)ans|=query(rs,mid+1,r);
29     return ans;
30 }
31 int main(){
32     scanf("%d%d%d",&n,&m,&q),build(1,1,n);
33     for(int a,b;q--;){
34         char s[2];scanf("%s",s);
35         if(s[0]==‘C‘)scanf("%d%d%d",&a,&b,&C),L=min(a,b),R=max(a,b),update(1,1,n);
36         else scanf("%d%d",&a,&b),L=min(a,b),R=max(a,b),printf("%d\n",count(query(1,1,n)));
37     }
38     return 0;
39 }

原文地址:https://www.cnblogs.com/JasonCow/p/12347045.html

时间: 2024-10-04 15:08:44

C++-POJ2777-Count Color[线段树][lazy标记][区间修改]的相关文章

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

fzu 2171 线段树 lazy标记

http://acm.fzu.edu.cn/problem.php?pid=2171      Problem 2171 防守阵地 II Accept: 73    Submit: 256Time Limit: 3000 mSec    Memory Limit : 32768 KB Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵

POJ 3468 线段树+lazy标记

lazy标记 Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to

线段树lazy标记??Hdu4902

Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 335    Accepted Submission(s): 159 Problem Description There is an old country and the king fell in love with a devil. The devil al

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 线段树

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

[hiho 22]线段树-lazy标记的下放

题目描述 之前提到过,线段树之所以更新查询快,是因为区间更新有lazy标记使得不需要每次都操作到叶子节点. 但是如果要操作一个节点时,其父节点上的lazy标记应当被释放,否则该节点无法得到最新的正确结果. 因而lazy标记下放的策略是在需要操作某个节点的子节点时,将该节点的lazy标记全部下放.见第69行. 同时应当注意,给某个节点增加lazy标记时,不要忘了修改该节点的相关统计值.因为更新完该节点后还要马上修改其父节点的统计值.见第80行. 代码如下: #include <stdio.h>