hdu1556 Color the ball(简单线段树)
只需要支持区间修改操作,统计答案直接就把所有的区间下放,输出长度为1 的区间们
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=100005;
struct node
{
int sum,add;
int l,r;
}tr[maxn<<2];
void build(int k,int l,int r)
{
tr[k].add=0;
tr[k].l=l,tr[k].r=r;
if(l==r)
{
tr[k].sum=0;
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void pushdown(int k)
{
if(tr[k].add!=0)
{
tr[k<<1].add+=tr[k].add;
tr[k<<1].sum+=tr[k].add;
tr[k<<1|1].add+=tr[k].add;
tr[k<<1|1].sum+=tr[k].add;
tr[k].add=0;
}
}
void update(int k,int s,int t)
{
int l=tr[k].l,r=tr[k].r;
if(l>t||s>r) return;
if(l>=s&&r<=t)
{
tr[k].sum+=(r-l+1);
tr[k].add+=1;
return;
}
pushdown(k);
update(k<<1,s,t);
update(k<<1|1,s,t);
tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
int ans[maxn];
void cal(int k)
{
if(tr[k].l==tr[k].r)
{
ans[tr[k].l]=tr[k].sum;
return;
}
if(tr[k].add) pushdown(k);
cal(k<<1);
cal(k<<1|1);
}
int main()
{
int n;
int l,r;
while(cin>>n)
{
if(n==0) return 0;
memset(ans,0,sizeof(ans));
build(1,1,n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&l,&r);
update(1,l,r);
}
cal(1);
for(int i=1;i<n;i++) printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}