这是第一个入手线段树的区间修改的问题,区间修改本要该一整个区间包括这些结点和子结点的值,那么会非常麻烦,这里学习到了可以使用到laze数组先记录下需要修改的次数,然后等到查询的时候一步步对子节点进行传递和修改涂色次数tre值和子结点的laze数组的值。学习了该博客: http://blog.csdn.net/zip_fan/article/details/46775633
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mid int m = (l + r)>>1
const int maxn=100010;
int n,a,b;
int tre[maxn<<2],laz[maxn<<2];
void pushdown(int rt)
{
if(laz[rt]!=0)
{
tre[rt*2]+=laz[rt];
tre[rt*2+1]+=laz[rt];
laz[rt*2]+=laz[rt];
laz[rt*2+1]+=laz[rt];
laz[rt]=0;
}
}
void update(int l,int r,int rt,int x,int y)
{
if(x<=l&&y>=r)
{
tre[rt]++;
laz[rt]++;
return ;
}
pushdown(rt);
mid;
if(x<=m)
update(lson,x,y);
if(y>m)
update(rson,x,y);
}
int query(int l,int r,int rt,int x)
{
if(l==r)
{
return tre[rt];
}
pushdown(rt);
mid;
if(x<=m) return query(lson,x);
else return query(rson,x);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
memset(tre,0,sizeof(tre));
memset(laz,0,sizeof(laz));
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
update(1,n,1,a,b);
}
for(int i=1;i<=n;i++)
{
if(i==1)
printf("%d",query(1,n,1,1));
else
printf(" %d",query(1,n,1,i));
}
printf("\n");
}
return 0;
}