多重线段树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
 /*一个线段树代表一个颜色,统计全部颜色的线段树即可

线段树开l,r空间使用较高,可能卡内存

*/
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N=100010;
int n,m,q;
struct node{
int l,r,sum,lazy;
//懒标记,判断后面是否需要更新
}tr[31][N*4];
void pushup(int u,int s){
tr[s][u].sum=tr[s][u*2].sum|tr[s][u*2+1].sum;
}
void pushdown(int u,int s){
if(tr[s][u].lazy==1){
tr[s][u*2].sum=1;
tr[s][u*2+1].sum=1;
tr[s][u*2].lazy=1;
tr[s][u*2+1].lazy=1;
}
else if(tr[s][u].lazy==0){
tr[s][u*2].sum=0;
tr[s][u*2+1].sum=0;
tr[s][u*2].lazy=0;
tr[s][u*2+1].lazy=0;
}
tr[s][u].lazy=3;
}
void build(int u,int l,int r,int s){
tr[s][u]={l,r};
tr[s][u].lazy=3;
if(l==r){
if(s==1) {tr[s][u].sum=1;tr[s][u].lazy=1;}
return;
}
int mid=(l+r)/2;
build(u*2,l,mid,s);
build(u*2+1,mid+1,r,s);
pushup(u,s);
}
void change(int u,int l,int r,int s,int k){
if(tr[s][u].l>=l&&tr[s][u].r<=r){
tr[s][u].sum=k;
tr[s][u].lazy=k;
return;
}
pushdown(u,s);
int mid=(tr[s][u].l+tr[s][u].r)/2;
if(l<=mid) change(u*2,l,r,s,k);
if(r>mid) change(u*2+1,l,r,s,k);
pushup(u,s);
}
int query(int u,int l,int r,int s){
if(tr[s][u].l>=l&&tr[s][u].r<=r){
return tr[s][u].sum;
}
pushdown(u,s);
int mid=(tr[s][u].l+tr[s][u].r)/2;
int sum=0;
if(l<=mid) sum|=query(u*2,l,r,s);
if(r>mid) sum|=query(u*2+1,l,r,s);
return sum;
}
void solve()
{
cin>>n>>m>>q;
for(int i=1;i<=m;i++){
build(1,1,n,i);
}
while(q--){
char s;int l,r;
cin>>s>>l>>r;
if(l>r) swap(l,r);
if(s=='C'){
int k;cin>>k;
for(int i=1;i<=m;i++){
if(i==k){
change(1,l,r,i,1);
}else{
change(1,l,r,i,0);
}
}
}else{ int ans=0;
for(int i=1;i<=m;i++){
if(query(1,l,r,i)) ans++;
}
cout<<ans<<endl;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
solve();

return 0;
}