NKOJ -2295 涂色

本文介绍了一道关于线段树与Lazy标记的经典题目,通过详细的代码解析,展示了如何利用线段树进行区间更新与查询操作。文章重点在于Lazy标记的使用技巧,以及线段树的构建和维护。

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

这道题是要一道经典的线段修改与访问的题,即用lazy标记的经典题
首先,我们按照老套路,要建树(初始化)。
建完树后,我们就开始更新了,我们一条线段一条线段的更新:当
一条线段树上全没颜色是lazy标记为0;若全有颜色则lazy标记为1;
不然lazy标记为-1 
#include<cstdio>
#include<iostream>
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<l)update(l,r,i*2+1,to);
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));
}

转载于:https://www.cnblogs.com/c201904xyorz/p/9990783.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值