题意:一个长为L的板,分为L份。有两种操作,要么给一个区间着一种颜色(会覆盖掉以前的),要么询问一个区间颜色的种数。板的初始颜色为1,对于每个询问输出结果。
思路:线段树。颜色用位来表示。因为总共不超过30种颜色,int足够了。第一种颜色对应二进制1,第二种颜色对应二进制10......对于每个段,设一个flag,如果是纯色,flag为true。lazy思想就是在不需要的时候,不去维护小段的颜色情况,每次只维护尽可能大的段。最后统计的时候递归按位或就行了。
这是我的第一道线段树。。因为开空间不够大WA了一次。关于开空间我的理解是,树的形状可能是满二叉树的下面一层最左边和中间有叶子,得开三倍的空间。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#define INF 1000000
using namespace std;
//poj 2777
struct node{
int l;
int r;
int color;
bool flag;
};
node tree[300000];
void built(int n,int l,int r){
tree[n].color=1;
tree[n].l=l;
tree[n].r=r;
tree[n].flag=true;
if(l!=r){
int mid=(l+r)/2;
built(n*2,l,mid);
built(n*2+1,mid+1,r);
}
}
void update(int n,int l,int r,int val){
if(l==tree[n].l&&r==tree[n].r){
tree[n].color=val;
tree[n].flag=true;
return;
}
int mid=(tree[n].l+tree[n].r)/2;
if(tree[n].flag){
update(n*2,tree[n].l,mid,tree[n].color);
update(n*2+1,mid+1,tree[n].r,tree[n].color);
}
tree[n].flag=false;
if(r<=mid){
update(n*2,l,r,val);
}else{
if(l>=mid+1){
update(n*2+1,l,r,val);
}else{
update(n*2,l,mid,val);
update(n*2+1,mid+1,r,val);
}
}
}
int query(int n,int l,int r){
if(tree[n].flag&&tree[n].l<=l&&tree[n].r>=r){
return tree[n].color;
}
int mid=(tree[n].l+tree[n].r)/2;
if(r<=mid){
return query(n*2,l,r);
}else{
if(l>=mid+1){
return query(n*2+1,l,r);
}else{
return query(n*2,l,mid)|query(n*2+1,mid+1,r);
}
}
}
int Cnt(int val){
int re=0;
while(val){
if(val&1)re++;
val>>=1;
}
return re;
}
int main(){
int L;//长度
int T;//颜色数
int O;//操作数
while(cin>>L>>T>>O){
built(1,1,L);
while(O--){
char oper;
cin>>oper;
if(oper=='C'){//更新
int A,B,C;
scanf("%d%d%d",&A,&B,&C);if(B<A)swap(A,B);
int col=1;
col<<=(C-1);
update(1,A,B,col);
}
if(oper=='P'){//查询
int A,B;
scanf("%d%d",&A,&B);if(B<A)swap(A,B);
printf("%d\n",Cnt(query(1,A,B)));
}
}
}
return 0;
}
本文通过一道具体的题目,详细解析了如何使用线段树解决区间染色与查询问题。介绍了线段树的基本概念、实现细节及优化技巧。
413

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



