有一个长度为L厘米板,L是一个正整数,所以我们可以把它均匀地划分成L个部分,分别从左到右编号为1,2……L,每一个部分长度都为1厘米。现在我们必须给每个部分涂色,一个部分一种颜色,要求完成以下两种操作:
1.“C A B C1”:表示从A部分到B部分涂上C1颜色。
2.“P A B”:表示从A部分到B部分涂了几种颜色。
在我们的日常生活中,我们有非常少几种颜色(红色,绿色,蓝色,黄色…),所以你可以假设不同颜色的总数T是非常少。简单地说,我们表示颜色的名称为颜色1,颜色2,…..颜色T。最初时候,这个厘米版都涂成颜色1。
输入文件的第一行包含三个整数L(1<=L<=10^5),T(1<=T<=30)和M(1<=M<=10^5)。M表示操作的次数。
以下M行,每行包含“C A B C1”或者“P A B”(A,B,C1都是整数,A可以比B大)。
输出文件依顺序输出,每行一个数字。
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
2
1
线段树,维护当前线段的颜色
懒标记一下,找到就退。
将颜色状压塞进线段树里面,可以节约时间。
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
const int maxn=100000;
struct Tree {
int left,right,color,sum;
};
struct Segment_Tree {
Tree tree[maxn*4];
int ans;
void build(int index,int Left,int Right) {
tree[index].left=Left;
tree[index].right=Right;
tree[index].color=tree[index].sum=1;
if(Left==Right)return;
int mid=(Left+Right)/2;
build(2*index,Left,mid);
build(2*index+1,mid+1,Right);
}
void push_down(int index) { //标记下传,下传当前lazy
if(!tree[index].color)return;
tree[index*2].sum=tree[index*2+1].sum=tree[index].sum;
tree[index*2].color=tree[index*2+1].color=tree[index].color;
tree[index].color=0;
}
void push_up(int index) { //标记上传,合并子树信息
tree[index].sum=tree[index*2].sum|tree[index*2+1].sum;
}
void modify(int index,int Left,int Right,int data) {
if(Rightindex].left||Left>tree[index].right)return; //不相交
if(Left<=tree[index].left&&Right>=tree[index].right) { //完全包含
tree[index].color=tree[index].sum=data;
return;
}
push_down(index); //标记下传
modify(index*2,Left,Right,data);
modify(index*2+1,Left,Right,data);
push_up(index); //标记上传
}
void init() {
ans=0;
}
void Query(int index,int Left,int Right) {
if(Rightindex].left||Left>tree[index].right)return; //不相交
if(Left<=tree[index].left&&Right>=tree[index].right) { //完全包含
ans|=tree[index].sum;
return;
}
push_down(index); //标记下传
Query(index*2,Left,Right);
Query(index*2+1,Left,Right);
push_up(index); //标记上传
}
};
Segment_Tree st;
int n,cn,m;
int main() {
scanf("%d%d%d",&n,&cn,&m);
st.build(1,1,n);
for(int i=1; i<=m; i++) {
char order;
getchar();
scanf("%c",&order);
if(order=='C') {
int Left,Right,color;
scanf("%d%d%d",&Left,&Right,&color);
if(Left>Right)swap(Left,Right);
st.modify(1,Left,Right,1<<(color-1));
} else {
int Left,Right;
scanf("%d%d",&Left,&Right);
if(Left>Right)swap(Left,Right);
st.init();
st.Query(1,Left,Right);
int cnt=0,tmp=st.ans;
while(tmp) {
if(tmp&1)cnt++;
tmp>>=1;
}
printf("%d\n",cnt);
}
}
return 0;
}