题目大意:给你一个长度为n的线段(n<1000000),还有t种颜料(m<30)。有以下两种操作:
#include<stdio.h>
#include<string.h>
#define maxn 100010
struct node
{
int l,r;//线段树区间
int mid;//线段树区间中间值
int mark;//
}p[maxn<<2];
int v[32];
void build(int id,int l,int r)
{
p[id].l=l;
p[id].r=r;
p[id].mid=(l+r)>>1;
p[id].mark=1;
if(l==r) return;
build(2*id,l,p[id].mid);
build(2*id+1,p[id].mid+1,r);
}
void update(int id,int l,int r,int val)
{
if(p[id].l==l&&p[id].r==r){
p[id].mark=val;
return;
}
if(p[id].mark==val) return;
if(p[id].mark!=0){
p[id*2].mark=p[id].mark;
p[id*2+1].mark=p[id].mark;
p[id].mark=0;
}
if(p[id].mid>=r) update(2*id,l,r,val);
else if(p[id].mid<l) update(id*2+1,l,r,val);
else{
update(id*2,l,p[id].mid,val);
update(id*2+1,p[id].mid+1,r,val);
}
}
void query(int id,int l,int r)
{
if(p[id].mark!=0){
v[p[id].mark]=1;
return;
}
if(p[id].mid>=r) query(id*2,l,r);
else if(p[id].mid<l) query(id*2+1,l,r);
else{
query(id*2,l,p[id].mid);
query(id*2+1,p[id].mid+1,r);
}
}
int main()
{
int n,m,b,c,d,i,t,tmp,count;
char str[5];
scanf("%d%d%d",&n,&m,&t);
build(1,1,n);
for(int j=0;j<t;j++)
{
scanf("%s%d%d",str,&b,&c);
if(b>c){
tmp=b;
b=c;
c=tmp;
}
if(str[0]=='C'){
scanf("%d",&d);
update(1,b,c,d);
}
else{
memset(v,0,sizeof(v));
query(1,b,c);
count=0;
for(i=1;i<=m;i++)
if(v[i]) count++;
printf("%d\n",count);
}
}
return 0;
}
本文介绍了一种使用线段树解决在线段区间内进行颜色更新和查询颜色种类数量问题的高效算法。该算法适用于大规模数据集,通过预处理和区间更新策略显著提高了操作效率。
2636

被折叠的 条评论
为什么被折叠?



