NKOJ -2295 涂色

http://oi.nks.edu.cn/en/Problem/Details/2295

这道题是要一道经典的线段修改与访问的题,即用lazy标记的经典题
首先,我们按照老套路,要建树(初始化)。
建完树后,我们就开始更新了,我们一条线段一条线段的更新:当
一条线段树上全没颜色是lazy标记为0;若全有颜色则lazy标记为1;
不然lazy标记为-1 
#include
#include
using namespace std;
struct tree{
int l,r,lazy;
}a[800005];
int s,n;
void buildtree(){//建树 
s=1;
while(s<200000)s*=2;
for(int i=s*2-1;i>=s;i--){
a[i].l=a[i].r=i-s+1;
a[i].lazy=0;
}
for(int i=s-1;i>=1;i--){
a[i].l=a[i*2].l;
a[i].r=a[i*2+1].r;
a[i].lazy=0;
}
}
void update(int l,int r,int i,int to){//更新 
if(l<=a[i].l&&r>=a[i].r){
a[i].lazy=to;
return ;
}
if(a[i].l==a[i].r)return ;
if(a[i].lazy!=-1){
a[i*2].lazy=a[i*2+1].lazy=a[i].lazy;
a[i].lazy=-1;
}
int mid=(a[i].l+a[i].r)/2;
if(r<=mid)update(l,r,i*2,to);
else if(mid else {
update(l,mid,i*2,to);
update(mid+1,r,i*2+1,to);
}
}
int ans;
int ask(int i){
if(a[i].lazy!=-1){//如果此线段全都有颜色或全都没有 
if(a[i].lazy==1){//如果全有颜色 
return a[i].r-a[i].l+1;
}
else return 0;
}
if(a[i].l==a[i].r)return 0;
return ask(i*2)+ask(i*2+1);
}
int x,y,z;
int m;
int main(){
scanf("%d",&n);
buildtree();
for(int i=1;i<=n;i++){
scanf("%d%d%d",&x,&y,&z);
m=max(m,z);
update(y,z-1,1,x);
}
printf("%d\n",ask(1));
}

你可能感兴趣的:(线段树)