题意:给你三个数,分别是长度,颜色种类和操作数。然后接下来那么多行操作,C x y z代表把x到y的涂成z颜色,Q x y代表询问x到y之间(包括x,y)有多少种不同的颜色并输出。起始颜色都是1。
思路:线段树成段跟新,询问。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int l,r,v;
}t[400005];
int n,tt,m;
char q[5];
bool vis[50];
void build(int ll,int rr,int rot)
{
t[rot].l=ll;
t[rot].r=rr;
t[rot].v=0;
if(ll==rr)return;
else
{
int mid=(ll+rr)/2;
build(ll,mid,rot<<1);
build(mid+1,rr,rot<<1|1);
}
}
void push(int rot)
{
t[rot<<1].v=t[rot<<1|1].v=t[rot].v;
t[rot].v=0;
}
void update(int ll,int rr,int c,int rot)
{
if(t[rot].l==ll&&t[rot].r==rr)
{
t[rot].v=c;
return;
}
else
{
if(t[rot].v)push(rot);
int mid=(t[rot].l+t[rot].r)/2;
if(rr<=mid)update(ll,rr,c,rot<<1);
else if(ll>mid)update(ll,rr,c,rot<<1|1);
else
{
update(ll,mid,c,rot<<1);
update(mid+1,rr,c,rot<<1|1);
}
}
}
int query(int ll,int rr,int rot)
{
if(t[rot].v)
{
if(!vis[t[rot].v])
{
vis[t[rot].v]=1;
return 1;
}
else return 0;
}
else
{
int mid=(t[rot].l+t[rot].r)/2;
if(rr<=mid)return query(ll,rr,rot<<1);
else if(ll>mid)return query(ll,rr,rot<<1|1);
else return query(ll,mid,rot<<1)+query(mid+1,rr,rot<<1|1);
}
}
int main()
{
int x,y,z;
scanf("%d%d%d",&n,&tt,&m);
build(1,n,1);
t[1].v=1;
for(int i=0;i<m;i++)
{
scanf("%s",q);
if(q[0]=='C')
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1);
}
else
{
scanf("%d%d",&x,&y);
memset(vis,0,sizeof(vis));
printf("%d\n",query(x,y,1));
}
}
return 0;
}