这个是基础的线段树的区间修改和单点查询的题,线段树的区间问题写法很套路,然而,区间修改问题有一个是我们需要注意的地方,那就是添加lazy标记,什么时候添加lazy标记和lazy标记
表示的是什么,这个需要明白,lazy标记表示的是整个区间的偏移量,当我们需要向下查找的时候,这个时候我们就需要下放lazy标记。另一个需要注意的地方是区间修改问题,一定要记得
pushup,这个很重要,还有递归返回值的问题,学的还是不扎实啊
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 110000
using namespace std;
int n;
//区间修改,单点查询
struct node{
int l,r,sum,lazy;
//lazy就是加上懒标记
}x[4*maxn+5];
void build(int l,int r,int p)
{
x[p].l=l;
x[p].r=r;
if(l==r) return;
build(l,(l+r)/2,p<<1);
build((l+r)/2+1,r,(p<<1)+1);
}
//延迟标记向下传 ,在哪个位置下传,这个很重要
void pushdown(int p)
{
if(x[p].lazy)
{
int a=(p<<1);
x[a].lazy+=x[p].lazy;
x[a+1].lazy+=x[p].lazy;
x[a].sum=x[a].sum+x[p].lazy*(x[a].r-x[a].l+1);
x[a+1].sum=x[a+1].sum+x[p].lazy*(x[a+1].r-x[a+1].l+1);
x[p].lazy=0;
}
}
//区间修改
void modi(int l,int r,int d,int p)
{
if(l>x[p].r||r<x[p].l) return;
if(l<=x[p].l&&r>=x[p].r) {x[p].sum=x[p].sum+d*(x[p].r-x[p].l+1);x[p].lazy+=d;return;}
else
{
int a=(p<<1);
pushdown(p);//需要下传的时候才下传,因为这个时候才是真正往下走的时候
if(r<=x[a].r) modi(l,r,d,a);
else if(l>=x[a+1].l) modi(l,r,d,a+1);
else
{
modi(l,x[a].r,d,a);
modi(x[a+1].l,r,d,a+1);
}
x[p].sum=x[p<<1].sum+x[p<<1|1].sum;
}
}
//单点查询
int query(int q,int p,int d)
{
//if(l>x[p].r||r<x[p].l) return 0;这句话写上就错了
int ans=0;
if(x[p].l==q&&x[p].r==q) return x[p].sum;
pushdown(p);
if(q>=x[p].l&&q<=x[p].r)
{
if(q<=x[p<<1].r) ans=query(q,p<<1,d);
else ans=query(q,(p<<1)+1,d);
}
return ans;
}
int main()
{
int a,b;
while(scanf("%d",&n)==1&&n!=0)
{
memset(x,0,sizeof(x));
build(1,n,1);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
modi(a,b,1,1);
}
// for(int i=1;i<=n;i++) query(i,1,1);
for(int i=1;i<=n-1;i++) printf("%d ",query(i,1,1));
printf("%d\n",query(n,1,1));
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 110000
using namespace std;
int n;
//区间修改,单点查询
struct node{
int l,r,sum,lazy;
//lazy就是加上懒标记
}x[4*maxn+5];
void build(int l,int r,int p)
{
x[p].l=l;
x[p].r=r;
if(l==r) return;
build(l,(l+r)/2,p<<1);
build((l+r)/2+1,r,(p<<1)+1);
}
//延迟标记向下传 ,在哪个位置下传,这个很重要
void pushdown(int p)
{
if(x[p].lazy)
{
int a=(p<<1);
x[a].lazy+=x[p].lazy;
x[a+1].lazy+=x[p].lazy;
x[a].sum=x[a].sum+x[p].lazy*(x[a].r-x[a].l+1);
x[a+1].sum=x[a+1].sum+x[p].lazy*(x[a+1].r-x[a+1].l+1);
x[p].lazy=0;
}
}
//区间修改
void modi(int l,int r,int d,int p)
{
if(l>x[p].r||r<x[p].l) return;
if(l<=x[p].l&&r>=x[p].r) {x[p].sum=x[p].sum+d*(x[p].r-x[p].l+1);x[p].lazy+=d;return;}
else
{
int a=(p<<1);
pushdown(p);//需要下传的时候才下传,因为这个时候才是真正往下走的时候
if(r<=x[a].r) modi(l,r,d,a);
else if(l>=x[a+1].l) modi(l,r,d,a+1);
else
{
modi(l,x[a].r,d,a);
modi(x[a+1].l,r,d,a+1);
}
x[p].sum=x[p<<1].sum+x[p<<1|1].sum;
}
}
//单点查询
int query(int q,int p,int d)
{
//if(l>x[p].r||r<x[p].l) return 0;这句话写上就错了
int ans=0;
if(x[p].l==q&&x[p].r==q) return x[p].sum;
pushdown(p);
if(q>=x[p].l&&q<=x[p].r)
{
if(q<=x[p<<1].r) ans=query(q,p<<1,d);
else ans=query(q,(p<<1)+1,d);
}
return ans;
}
int main()
{
int a,b;
while(scanf("%d",&n)==1&&n!=0)
{
memset(x,0,sizeof(x));
build(1,n,1);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
modi(a,b,1,1);
}
// for(int i=1;i<=n;i++) query(i,1,1);
for(int i=1;i<=n-1;i++) printf("%d ",query(i,1,1));
printf("%d\n",query(n,1,1));
}
return 0;
}