POJ 2777-Count Color(线段树-区间染色查询)

爱被打了一巴掌 2022-06-17 03:12 304阅读 0赞

Count Color














Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 45268   Accepted: 13705

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.

Sample Input

  1. 2 2 4
  2. C 1 1 2
  3. P 1 2
  4. C 2 2 2
  5. P 1 2

Sample Output

  1. 2
  2. 1

Source

POJ Monthly—2006.03.26,dodo

题目意思:

L长的木板染上T种颜色,有O个操作,其中C a b c表示a~b长度区间全部染成c这种颜色,Q a b表示查询区间a~b内不同颜色的个数。

解题思路:

线段树节点存储该区间内的颜色,单点区间肯定就是染成的颜色,大区间如果标记为-1则表示该区间由多种颜色的小区间组成,注意初始情况下木板均为同一种颜色,可以记为1。

一共有最多30种颜色,所以用bool vis[30]数组标记,在每次查询的时候清空,查询到点或区间颜色相同时,对该颜色标记为true,最后统计1~T这T种颜色使用的个数即vis是true的情况。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<iomanip>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #include<cstring>
  7. #include<map>
  8. #include<algorithm>
  9. #include<vector>
  10. #include<queue>
  11. using namespace std;
  12. #define INF 0xfffffff
  13. #define MAXN 275000
  14. bool vis[50];//1表示该区间有该颜色
  15. int ans[MAXN*4];
  16. struct Node //树
  17. {
  18. int l,r;//左右节点
  19. int col;//区间内的颜色
  20. };
  21. Node tree[MAXN*5];
  22. void BuildTree(int root, int l, int r)//建树
  23. {
  24. tree[root].l=l;
  25. tree[root].r=r;
  26. tree[root].col=1;//初始状态都是同一种颜色
  27. if(l!=r)
  28. {
  29. BuildTree(2*root,l,(l+r)/2);
  30. BuildTree(2*root+1,(l+r)/2+1,r);
  31. }
  32. }
  33. void Insert(int i,int l,int r,int c)//插入
  34. {
  35. if(tree[i].col==c)//同色
  36. return ;
  37. if(tree[i].l==l&&tree[i].r==r)
  38. {
  39. tree[i].col=c;//染色
  40. return ;
  41. }
  42. if(tree[i].col!=-1)//同色
  43. {
  44. tree[2*i].col=tree[2*i+1].col=tree[i].col;
  45. tree[i].col=-1;
  46. }
  47. int mid=(tree[i].l+tree[i].r)/2;
  48. if(r<=mid)
  49. Insert(2*i,l,r,c);
  50. else if(l>mid)
  51. Insert(2*i+1,l,r,c);
  52. else
  53. {
  54. Insert(2*i,l,mid,c);
  55. Insert(2*i+1,mid+1,r,c);
  56. }
  57. }
  58. void Query(int i,int l,int r)
  59. {
  60. if(tree[i].col!=-1)//同色
  61. {
  62. vis[tree[i].col]=true;
  63. return;
  64. }
  65. int mid=(tree[i].l+tree[i].r)/2;
  66. if(r<=mid)
  67. Query(2*i,l,r);
  68. else if(l>mid)
  69. Query(2*i+1,l,r);
  70. else
  71. {
  72. Query(2*i,l,mid);
  73. Query(2*i+1,mid+1,r);
  74. }
  75. }
  76. int main()
  77. {
  78. #ifdef ONLINE_JUDGE
  79. #else
  80. freopen("G:/cbx/read.txt","r",stdin);
  81. //freopen("G:/cbx/out.txt","w",stdout);
  82. #endif
  83. int l,t,n;
  84. scanf("%d%d%d\n",&l,&t,&n);
  85. //while(~scanf("%d%d%d\n",&l,&t,&n))
  86. {
  87. BuildTree(1,1,n);//建树
  88. while(n--)
  89. {
  90. char ch;
  91. cin>>ch;
  92. if(ch=='C')
  93. {
  94. int a,b,c;
  95. scanf("%d%d%d",&a,&b,&c);
  96. if(a>b) swap(a,b);//如果a>b
  97. Insert(1,a,b,c);
  98. }
  99. else if(ch=='P')
  100. {
  101. memset(vis,false,sizeof(vis));
  102. int a,b,ans=0;
  103. scanf("%d%d",&a,&b);
  104. if(a>b) swap(a,b);
  105. Query(1,a,b);
  106. for(int i=1; i<=t; ++i)
  107. if(vis[i]) ++ans;
  108. printf("%d\n",ans);
  109. }
  110. }
  111. }
  112. return 0;
  113. }

发表评论

表情:
评论列表 (有 0 条评论,304人围观)

还没有评论,来说两句吧...

相关阅读