这里用到lazy的思想,每次传递num值,num==-1表示这个区间的颜色不只有一个剩下的代码把
#include <map>
#include <set>
#include <list>
#include <cmath>
#include<cctype>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b)
{
return a % b == 0 ? b : gcd(b, a % b);
}
struct node
{
int l;int r;
int num;//num保存颜色编号,如果当前区间包含的颜色不是一个那么这个编号为-1,递归到子树来查找
}tree[400005];
int vis[32];
void buildtree(int id ,int l ,int r)
{
tree[id].l=l;tree[id].r=r;
tree[id].num=1;
if (l==r)return ;
int m=(l+r)/2;
buildtree(id*2,l,m);
buildtree(id*2+1,m+1,r);
}
void update(int id,int l,int r,int c)
{
if (tree[id].l==l && tree[id].r==r)
{
tree[id].num=c;
return ;
}
if (tree[id].num==c)return;
//下面这种情况就是当前区间颜色编号不是c,那么添加编号后该区间颜色编号为多个
if (tree[id].num!=-1)
{
tree[id*2].num=tree[id].num;
tree[id*2+1].num=tree[id].num;
tree[id].num=-1;
}
int m=(tree[id].l+tree[id].r)/2;
if (l>m)
update(id*2+1,l,r,c);
else if (r<=m)
update(id*2,l,r,c);
else
{
update(id*2,l,m,c);
update(id*2+1,m+1,r,c);
}
}
void query(int id ,int l ,int r)
{
if (tree[id].num!=-1) {vis[tree[id].num]=1;return ;}
int m=(tree[id].l+tree[id].r)/2;
if (l>m) query(id*2+1,l,r);
else if (r<=m) query(id*2,l,r);
else
{
query(id*2,l,m);
query(id*2+1,m+1,r);
}
}
int main()
{
int L,T,O;
scanf("%d%d%d",&L,&T,&O);
char input[3];
buildtree(1,1,L);
memset(vis,0,sizeof(vis));
for (int i=0;i<O;i++)
{
scanf("%s",input);
int a,b,c;
if (input[0]=='C')
{
scanf("%d%d%d",&a,&b,&c);
update(1,a,b,c);
}
else
{
memset(vis,0,sizeof(vis));
int ans=0;
scanf("%d%d",&a,&b);
query(1,a,b);
for (int i=1;i<=T;i++)
if (vis[i]) ans++;
printf("%d\n",ans);
}
}
return 0;
}