题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556
2.整合函数struct Node{
int add; //延迟标记
int sum;
int l;
int r;
}c[MAX*3];
3.建树函数void up(int rt)
{
c[rt].sum=c[rt<<1].sum+c[rt<<1|1].sum;
}
4.延迟更新函数void create(int rt,int l,int r)
{
c[rt].l=l;
c[rt].r=r;
c[rt].add=0;
if(c[rt].l==c[rt].r)
{
c[rt].sum=0;
return;
}
int mid=(l+r)>>1;
create(rt<<1,l,mid);
create(rt<<1|1,mid+1,r);
up(rt);
return;
}
void down(int rt)
{
int m=c[rt].r-c[rt].l+1; //m为该区间段的点数
if(c[rt].add) //该区间段是否已被延迟更新,如果没有则退出,否则更新子节点
{
c[rt<<1].add+=c[rt].add; //更新左儿子节点的add值
c[rt<<1|1].add+=c[rt].add;
c[rt<<1].sum+=(m-(m>>1))*c[rt].add; //更新左儿子节点的sum值
c[rt<<1|1].sum+=(m>>1)*c[rt].add;
c[rt].add=0; //将该区间段标记为已更新
}
}
6.查询函数void update(int rt,int l,int r)
{
if(l<=c[rt].l&&c[rt].r<=r)
{
c[rt].sum+=c[rt].r-c[rt].l+1;
c[rt].add++;
return;
}
down(rt); //将区间段进行延迟操作
int mid=(c[rt].l+c[rt].r)>>1;
if(l<=mid)
update(rt<<1,l,r);
if(mid<r)
update(rt<<1|1,l,r);
up(rt);
return;
}
完整代码:int query(int rt,int l,int r)
{
if(l<=c[rt].l&&c[rt].r<=r)
{
return c[rt].sum;
}
down(rt); //将区间段进行延迟操作
int mid=(c[rt].l+c[rt].r)>>1;
int le=0,re=0;
if(l<=mid)
le=query(rt<<1,l,r);
if(mid<r)
re=query(rt<<1|1,l,r);
return le+re;
}
#include<stdio.h>
#define MAX 100000
struct Node{
int add;
int sum;
int l;
int r;
}c[MAX*3];
void down(int rt)
{
int m=c[rt].r-c[rt].l+1;
if(c[rt].add)
{
c[rt<<1].add+=c[rt].add;
c[rt<<1|1].add+=c[rt].add;
c[rt<<1].sum+=(m-(m>>1))*c[rt].add;
c[rt<<1|1].sum+=(m>>1)*c[rt].add;
c[rt].add=0;
}
}
void up(int rt)
{
c[rt].sum=c[rt<<1].sum+c[rt<<1|1].sum;
}
void create(int rt,int l,int r)
{
c[rt].l=l;
c[rt].r=r;
c[rt].add=0;
if(c[rt].l==c[rt].r)
{
c[rt].sum=0;
return;
}
int mid=(l+r)>>1;
create(rt<<1,l,mid);
create(rt<<1|1,mid+1,r);
up(rt);
return;
}
void update(int rt,int l,int r)
{
if(l<=c[rt].l&&c[rt].r<=r)
{
c[rt].sum+=c[rt].r-c[rt].l+1;
c[rt].add++;
return;
}
down(rt);
int mid=(c[rt].l+c[rt].r)>>1;
if(l<=mid)
update(rt<<1,l,r);
if(mid<r)
update(rt<<1|1,l,r);
up(rt);
return;
}
int query(int rt,int l,int r)
{
if(l<=c[rt].l&&c[rt].r<=r)
{
return c[rt].sum;
}
down(rt);
int mid=(c[rt].l+c[rt].r)>>1;
int le=0,re=0;
if(l<=mid)
le=query(rt<<1,l,r);
if(mid<r)
re=query(rt<<1|1,l,r);
return le+re;
}
int main()
{
int n,i;
int l,r;
while(scanf("%d",&n),n)
{
create(1,1,n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&l,&r);
update(1,l,r);
}
for(i=1;i<=n;i++)
{
int num;
num=query(1,i,i);
if(i!=1)
printf(" ");
printf("%d",num);
}
printf("\n");
}
return 0;
}