查询和修改给定区间的颜色种类,将一个区间的颜色种类k用二进制数2^k表达,位运算求或即可得出任意区间的不同颜色种类。
查询量巨大,建议按线段更新,不要每次都更新到树叶。
我也不明白我的程序怎么那么慢。。。 求xxms做法。
1
/**//*Source Code
2
3
Problem: 2777 User: _mTy
4
Memory: 4024K Time: 329MS
5
Language: C++ Result: Accepted
6
7
*/
8
#include<stdio.h>
9
#include<string.h>
10
#define MAXV 666666
11
#define swap(a,b) a^=b^=a^=b
12
13
typedef unsigned long _UL;
14
typedef _UL ele_t;
15
ele_t data[MAXV];
16
int B[MAXV],E[MAXV],LSON[MAXV],RSON[MAXV],C[MAXV];
17
int cnt;
18
bool fill[MAXV];
19
// B[] E[] 存放 [a,b]左界 右界
20
// C[] 覆盖当前区间的线段数
21
// LSON,RSON 点v的左右儿子的数组下标
22
// fill[] 指示特定区间是否仅被一种颜色填充
23
24
void ini(int u,int v)
{
25
int i;
26
++cnt; i = cnt; B[i] = u; E[i] = v;
27
if( v - u >= 1 )
{
28
LSON[i] = cnt+1; ini(u,(u+v)/2);
29
RSON[i] = cnt+1; ini((u+v)/2+1,v);
30
}
31
}
32
33
void insert(int u,int v,int r,ele_t ele)
{ // 将区间[u,v]信息 data 插入以 r 为根的线段树
34
if( u <= B[r] && v >= E[r] )
{
35
data[r] = 1UL<<ele-1;
36
fill[r] = 1;
37
}else
{
38
if( fill[r] == 1 )
{ data[LSON[r]] = data[RSON[r]] = data[r]; fill[LSON[r]] = fill[RSON[r]] = 1; }
39
40
if( u <= (B[r]+E[r])/2 ) insert(u,v,LSON[r],ele);
41
if( v >= (B[r]+E[r])/2+1 ) insert(u,v,RSON[r],ele);
42
43
// updata [u,v]
44
data[r] = data[LSON[r]] | data[RSON[r]];
45
fill[r] = 0;
46
}
47
}
48
49
_UL out(int u,int v,int r)
{
50
int data_1 = 0,data_2 = 0;
51
if( fill[r] == 1 || u <= B[r] && v >= E[r] ) return data[r];
52
else
{
53
if( u <= (B[r]+E[r])/2 ) data_1 = out(u,v,LSON[r]);
54
if( v >= (B[r]+E[r])/2+1 ) data_2 = out(u,v,RSON[r]);
55
return data_1 | data_2;
56
}
57
}
58
59
int main()
{
60
int i,j,l,t,o,u,v,cc,res;
61
_UL val;
62
char chr;
63
while(scanf("%d%d%d",&l,&t,&o)!=EOF)
{
64
getchar();
65
66
data[1] = 1UL;
67
cnt = 0; ini(1,l);
68
memset(fill,0,sizeof(bool)*(cnt+1)); fill[1] = 1; // 初始区间 [u,v] 被1颜色填充
69
70
for(i=0;i<o;i++)
{
71
scanf("%c%d%d",&chr,&u,&v);
72
if( u>v ) swap(u,v);
73
if( chr == 'C' )
{
74
scanf("%d",&cc);
75
getchar();
76
insert(u,v,1,cc);
77
}else
{
78
getchar();
79
val = out(u,v,1);
80
res = 0;
81
for(j=0;j<t;j++) if( val & 1UL<< j ) ++res;
82
printf("%d\n",res);
83
}
84
}
85
}
86
return 0;
87
}