题目背景
阿宝上学了,今天老师拿来了一块很长的涂色板。
题目描述
色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格。并从左到右标记为1, 2, … L。现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:1. “C A B C” 指在A到 B 号方格中涂上颜色 C。2. “P A B” 指老师的提问:A到 B号方格中有几种颜色。学校的颜料盒中一共有 T 种颜料。为简便起见,我们把他们标记为 1, 2, … T. 开始时色板上原有的颜色就为1号色。 面对如此复杂的问题,阿宝向你求助,你能帮助他吗?
输入输出格式
输入格式:
第一行有3个整数 L (1 <= L <= 100000), T (1 <= T <= 30) 和 O (1 <= O <= 100000). 在这里O表示事件数, 接下来 O 行, 每行以 “C A B C” 或 “P A B” 得形式表示所要做的事情(这里 A, B, C 为整数, 可能A> B)
输出格式:
对于老师的提问,做出相应的回答。每行一个整数。
输入输出样例
输入样例#1:
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
输出样例#1:
2
1
#include
#include
#include
#include
#include
#include
using namespace std;
struct Node{
int l,r,col[31],sum,lazy_change;
Node *son[2];
}*root;
int L,T,O;
void UpDate(Node *cur){
for(int i=1;i<=T;i++){
cur->col[i] = cur->son[0]->col[i] +
cur->son[1]->col[i];
if(cur->col[i]) cur->sum++;
}
return;
}
void Built(Node *&cur,int l,int r){
cur = new Node;
cur->l=l; cur->r=r;
cur->sum=0; cur->lazy_change=0;
for(int i=1;i<=T;i++) cur->col[i] = 0;
if(l==r){
cur->col[1]=1;cur->sum=1;
return;
}
int mid=(l+r)>>1;
Built(cur->son[0],l,mid);
Built(cur->son[1],mid+1,r);
UpDate(cur);
return;
}
void Down(Node* cur){
for(int i=1;i<=T;i++)
cur->son[0]->col[i] = cur->son[1]->col[i] =0;
cur->son[0]->col[ cur->lazy_change ]
= cur->son[1]->col[ cur->lazy_change ] = 1;
cur->son[1]->lazy_change =
cur->son[0]->lazy_change = cur->lazy_change;
cur->son[1]->sum = cur->son[0]->sum = 1;
cur->lazy_change=0;
}
void Change(Node* cur,int l,int r,int x){
if(l == cur->l&&cur->r ==r){
cur->sum=1;
for(int i=1;i<=T;i++) cur->col[i]=0;
cur->col[x]=1;cur->lazy_change=x;
return ;
}
if(cur->lazy_change) Down(cur);
int mid=(cur->l + cur->r)>>1;
if(l>mid) Change(cur->son[1],l,r,x);
else if(r<=mid) Change(cur->son[0],l,r,x);
else Change(cur->son[0],l,mid,x),
Change(cur->son[1],mid+1,r,x);
UpDate(cur);
}
int flag[35];
void Query(Node* cur,int l,int r){
if(l == cur->l && cur->r == r){
for(int i=1;i<=T;i++) flag[i] += cur->col[i];
return ;
}
if(cur->lazy_change) Down(cur);
int mid=(cur->l + cur->r) >>1;
if(l>mid) Query(cur->son[1],l,r);
else if(r<=mid) Query(cur->son[0],l,r);
else Query(cur->son[0],l,mid)
,Query(cur->son[1],mid+1,r);
return ;
}
int solve(){
int ans=0;
for(int i=1;i<=T;i++) if(flag[i]) ans++;
return ans;
}
int main(){
scanf("%d%d%d",&L,&T,&O);
Built(root,1,L);
char C;
int L,R,X;
while(O--){
cin>>C;
if(C=='C'){
scanf("%d%d%d",&L,&R,&X);
if(L>R) swap(L,R);
Change(root,L,R,X);
}
else if(C=='P'){
scanf("%d%d",&L,&R);
if(L>R) swap(L,R);
memset(flag,0,sizeof flag );
Query(root,L,R);
printf("%d\n",solve());
}
}
return 0;
}