Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.
There is a very long board with length L centimeter, L is a positive integer, so we can evenly divide the board into L segments, and they are labeled by 1, 2, … L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board:
- “C A B C” Color the board from segment A to segment B with color C.
- “P A B” Output the number of different colors painted between segment A and segment B (including).
In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, … color T. At the beginning, the board was painted in color 1. Now the rest of problem is left to your.
Input
First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains “C A B C” or “P A B” (here A, B, C are integers, and A may be larger than B) as an operation defined previously.
Output
Ouput results of the output operation in order, each line contains a number.
Sample Input
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
Sample Output
2
1
#include<iostream>
#include<cstdio>
#include<sstream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<fstream>
using namespace std;
const int maxn=1e5+10;
int color[35];
struct node{
int l,r,num,lazy;
}a[maxn<<2];
int result;
void update(int k)
{
a[k].num=a[k<<1].num|a[k<<1|1].num;
}
void build(int k,int l,int r)
{
a[k].l=l;
a[k].r=r;
if(l==r)
{
a[k].num=1;
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}
void pushdown(int k)
{
if(!a[k].lazy) return;
a[k<<1].num=a[k].lazy;
a[k<<1|1].num=a[k].lazy;
a[k<<1].lazy=a[k<<1|1].lazy=a[k].lazy;
a[k].lazy=0;
update(k);
return;
}
void change(int k,int l,int r,int t)
{
if(a[k].l>=l&&a[k].r<=r)
{
a[k].lazy=t;
a[k].num=t;
return;
}
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid) change(k<<1,l,r,t);
if(r>mid) change(k<<1|1,l,r,t);
update(k);
}
void solve(int k,int l,int r)
{
if(a[k].l>=l&&a[k].r<=r)
{
result=result|a[k].num;
return ;
}
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid) solve(k<<1,l,r);
if(r>mid) solve(k<<1|1,l,r);
update(k);
}
int main()
{
int n,T,o;
while(scanf("%d%d%d",&n,&T,&o)!=EOF)
{
build(1,1,n);
for(int i=1;i<=o;i++)
{
char ch;
cin>>ch;
switch(ch)
{
case 'C':
{
int l,r,t;
scanf("%d%d%d",&l,&r,&t);
if(l<r) change(1,l,r,1<<(t-1));
else change(1,r,l,1<<(t-1));
break;
}
case 'P':
{
int l,r;
result=0;
scanf("%d%d",&l,&r);
if(l<r) solve(1,l,r);
else solve(1,r,l);
int sum=0;
while(result>0)
{
sum++;
result-=result&(-result);
}
printf("%d\n",sum);
break;
}
}
}
}
return 0;
}