线段树模板题,求个数时遇到set标记就返回
由于个数较少,可以用long long压位暴力处理

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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Tree
{
int L,R,col;
}T[400005];
inline void pushdown(int v)
{
if(T[v].col!=-1)
{
T[v<<1].col=T[(v<<1)|1].col=T[v].col;
T[v].col=-1;
}
return;
}
inline void Build(int L,int R,int v)
{
T[v].L=L;T[v].R=R;
T[v].col=1;
if(L==R)return;
int mid=(L+R)>>1;
Build(L,mid,v<<1);
Build(mid+1,R,(v<<1)|1);
return;
}
inline void Insert(int L,int R,int col,int v)
{
if(L>T[v].R||R<T[v].L)return;
if(L<=T[v].L&&R>=T[v].R)
{
T[v].col=col;
return;
}
pushdown(v);
Insert(L,R,col,v<<1);
Insert(L,R,col,(v<<1)|1);
return;
}
inline long long Query(int L,int R,int v)
{
if(L>T[v].R||R<T[v].L)return 0;
if(T[v].col!=-1)return 1LL<<T[v].col;
return Query(L,R,v<<1)|Query(L,R,(v<<1)|1);
}
int main(void)
{
int i,n,m,k,ch,L,R,v;
scanf("%d%d%d",&n,&k,&m);
Build(1,n,1);
while(m--)
{
while(ch=getchar())if(ch=='C'||ch=='P')break;
scanf("%d%d",&L,&R);
if(ch=='C')
{
scanf("%d",&v);
Insert(L,R,v,1);
}
else printf("%d\n",__builtin_popcount(Query(L,R,1)));
}
return 0;
}