count color线段树java_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 divide the board into L segments, and they are labeled by 1, 2, ... L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board:

1. "C A B C" Color the board from segment A to segment B with color C.

2. "P A B" Output the number of different colors painted between segment A and segment B (including).

In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, ... color T. At the beginning, the board was painted in color 1. Now the rest of problem is left to your.

Input

First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains "C A B C" or "P A B" (here A, B, C are integers, and A may be larger than B) as an operation defined previously.

Output

Ouput results of the output operation in order, each line contains a number.

简而言之,一条一维的线,反复地给某一连续段涂色,后涂的色覆盖先涂的色,要求一边涂一边随时接受问询,回答某一段有多少种颜色。

很明显的线段树题。

几个key point:一、由于颜色数量比较少,利用了2进制来存储数据。cnt【x】的二进制表达中的第i位为1代表这段板上有第i种颜色。

二、lazy数组,当一整块涂色的时候先不急着向下更新子节点,把lazy置成1表示子区间未更新。当需要知道的时候再pushdown一层,还需要的话再继续pushdown。很懒吧233.

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3 #include

4 using namespacestd;5 #define lson l,m,rt<<1

6 #define rson m+1,r,rt<<1|1

7 const int MAXN=100010;8 int cnt[MAXN<<2];9 int lazy[MAXN<<2];10

11 void pushup(intrt)12 {13 cnt[rt]=cnt[rt<<1]|cnt[rt<<1|1];14 //printf("cnt=%d %d %d %d\n",cnt[rt],cnt[rt<<1],cnt[rt<<1|1],rt<<1|1);

15 }16 void pushdown(intrt)17 {18 if(lazy[rt])19 {20 cnt[rt<<1]=cnt[rt];21 cnt[rt<<1|1]=cnt[rt];22 lazy[rt<<1]=1;23 lazy[rt<<1|1]=1;24 lazy[rt]=0;25 }26 }27 int query(int a,int b,int l,int r,intrt)28 {29 //printf("a\n");30 //printf("query %d %d %d %d %d\n",a,b,l,r,rt);

31 if(a<=l&&b>=r) returncnt[rt];32 pushdown(rt);33 int t1=0,t2=0;34 int m=(r+l)>>1;35 if(a<=m) t1=query(a,b,lson);36 if(b>m) t2=query(a,b,rson);37 //printf("query %d %d %d %d %d t1=%d t2=%d\n",a,b,l,r,rt,t1,t2);

38 return t1|t2;39 }40

41 void update(int a,int b,int c,int l,int r,intrt)42 {43 //printf("update %d %d %d %d %d %d\n",a,b,c,l,r,rt);

44 if(a<=l&&b>=r)45 {46 cnt[rt]=1<

49 return;50 }51 pushdown(rt);52 int m=(l+r)>>1;53 if(a<=m) update(a,b,c,lson);54 if(b>m) update(a,b,c,rson);55 pushup(rt);56 }57 intmain()58 {59 //freopen("in.txt","r",stdin);60 //freopen("out.txt","w",stdout);

61 intlen,numtype,oper,a,b,c,tmp,t,ans;62 chartype;63 scanf("%d%d%d",&len,&numtype,&oper);64 for(int i=0;i

74 if(type[0]=='C')75 {76 scanf("%d%d%d",&a,&b,&c);77 if(a>b)78 {79 t=a;a=b;b=t;80 }81 update(a,b,c,1,len,1);82 }83 else

84 {85 scanf("%d%d",&a,&b);86 if(a>b)87 {88 t=a;a=b;b=t;89 }90 tmp=query(a,b,1,len,1);91 for(ans=0;tmp>=1;tmp>>=1)92 {93 //printf("tmp=%d\n",tmp);

94 if(tmp&1) ans++;95 }96 printf("%d\n",ans);97 }98 }99 return 0;100 }

View Code

03-15
### 关于 POJ 2286 的解决方案 POJ 平台上的题目编号通常对应特定算法或数据结构的应用场景。对于 POJ 2286,虽然未提供具体描述,但从其编号范围推测可能涉及动态规划、贪心策略或其他经典算法。 #### 动态规划方法 如果该问题是关于寻找友好数对的数量,则可以采用如下思路解决: 定义两个数组 `sum_divisors` 和 `friend_pairs` 来分别存储每个数的因子和以及已找到的友好数对数量。通过遍历小于给定上限的所有整数 \( n \),计算它们的因子之和并验证是否存在对应的友好数关系[^2]。 以下是实现这一逻辑的一个 Python 示例代码: ```python def calculate_friend_numbers(limit): sum_divisors = [0] * (limit + 1) # 计算所有数的因子和 for i in range(1, limit + 1): for j in range(i * 2, limit + 1, i): sum_divisors[j] += i friend_count = 0 seen_friends = set() # 验证每一对是否构成友好数字 for num in range(1, limit + 1): partner = sum_divisors[num] if ( partner < limit and partner != num and sum_divisors[partner] == num and (num, partner) not in seen_friends ): friend_count += 1 seen_friends.add((num, partner)) seen_friends.add((partner, num)) # 对称处理 return friend_count print(calculate_friend_numbers(10000)) # 输出小于一万的友好数量 ``` 上述代码实现了基于因子求和的方法来查找指定范围内所有的友好数对,并统计总数。 #### 数据结构优化 如果是类似于 **Balanced Lineup** 这样的区间最值查询问题,则需考虑高效的数据结构支持快速访问操作。例如使用线段树或者稀疏表(Sparse Table),可以在 O(log N) 或更低的时间复杂度下完成多次询问响应[^3]。 假设输入是一系列牛的高度序列,目标是最小化任意连续子列中的最大高度差。那么预处理阶段构建辅助索引之后,在每次请求到来时只需执行常数级运算即可得出结果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值