N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
当N = 0,输入结束。
3
1 1
2 2
3 3
3
1 1
1 2
1 3
0
1 1 1
3 2 1
这还是模板题
pushdown的作用就是相当于把父节点的值分发给两个子节点
每次不符合 所以往下一层就够了
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100005;
int sum[maxn*4];
struct node
{
int l,r,val,mark;
}tree[maxn*4];
void build(int i,int l,int r)
{
tree[i].mark=0;
tree[i].val=0;
tree[i].l=l,tree[i].r=r;
//cout<<l<<" "<<r<<endl;
if(l==r)return;
int m=(l+r)/2;
build(i*2,l,m);
build(i*2+1,m+1,r);
}
void pushdown(int i,int v)
{
if(tree[i].mark!=0)
{
tree[i*2].mark+=tree[i].mark;
tree[i*2+1].mark+=tree[i].mark;
tree[i*2+1].val+=tree[i].mark*(v/2); //区间中的个数
tree[i*2].val+=tree[i].mark*(v-v/2);
tree[i].mark=0;
}
}
void update(int i,int l,int r,int add)
{
if(tree[i].l==l&&r==tree[i].r) //要更新的区间比i所含的区间大 全部包含
{
tree[i].mark+=add;
tree[i].val+=add*(tree[i].r-tree[i].l+1);
//cout<<tree[i].l<<" "<<tree[i].r<<" "<<tree[i].mark<<" "<<tree[i].val<<endl;
return;
}
if(tree[i].mark!=0)pushdown(i,tree[i].r-tree[i].l+1);
//cout<<tree[i].l<<" "<<tree[i].r<<" "<<tree[i].mark<<" "<<tree[i].val<<endl;
int m=(tree[i].l+tree[i].r)/2;
if(r<=m)update(i*2,l,r,add);
else if(l>m)update(i*2+1,l,r,add);
else
{
update(i*2,l,m,add);
update(i*2+1,m+1,r,add);
}
tree[i].val=tree[i*2].val+tree[i*2+1].val;
}
int query(int i,int l,int r)
{
//cout<<tree[i].l<<" "<<tree[i].r<<" "<<tree[i].mark<<" "<<tree[i].val<<endl;
if(tree[i].l>=l&&tree[i].r<=r)
return tree[i].val;
pushdown(i,tree[i].r-tree[i].l+1);
int ans=0;
int m=(tree[i].l+tree[i].r)/2;
if(l<=m)ans+=query(i*2,l,r);
if(r>m)ans+=query(i*2+1,l,r);
return ans;
}
int main()
{
int n;
while(cin>>n&&n)
{
build(1,1,n);
int a,b;
int k=n;
while(n--)
{
scanf("%d%d",&a,&b);
update(1,a,b,1);
}
for(int i=1;i<=k;i++)
{
if(i!=k)cout<<query(1,i,i)<<" ";
else cout<<query(1,k,k)<<endl;
}
}
return 0;
}