题意:有n个球,1~n,n个操作:(a,b),意思是把区间[a,b]里的球都涂一遍色,n次操作后,问每个球分别被涂了多少次。
分析:
区间更新,单点查询。一般区间更新都要用lazy[rt],不然对线段树的更新操作就退化为了暴力更新,会超时。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100000;
int n;
int tot[maxn*4+10],lazy[maxn*4+10];
struct node{
int l,r;
}tree[maxn*4+10];
void pushup(int rt)
{
tot[rt]=tot[rt<<1]+tot[rt<<1|1];
}
void pushdown(int rt)
{
if(lazy[rt]!=0){
if(tree[rt].l==tree[rt].r){
tot[rt]+=lazy[rt];
return;
}
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
}
void creat(int l,int r,int rt)
{
tree[rt].l=l;
tree[rt].r=r;
lazy[rt]=0;
if(l==r){
tot[rt]=0;
return;
}
int mid=(l+r)>>1;
creat(l,mid,rt<<1);
creat(mid+1,r,rt<<1|1);
}
void upd(int a,int b,int rt)
{
if(a<=tree[rt].l&&b>=tree[rt].r){
lazy[rt]+=1;
return;
}
pushdown(rt);
int mid=(tree[rt].l+tree[rt].r)>>1;
if(a<=mid) upd(a,b,rt<<1);
if(b>mid) upd(a,b,rt<<1|1);
}
void query(int rt)
{
pushdown(rt);
if(tree[rt].l==tree[rt].r){
if(tree[rt].l==1) printf("%d",tot[rt]);
else printf(" %d",tot[rt]);
return;
}
query(rt<<1);
query(rt<<1|1);
}
int main()
{
while(scanf("%d",&n)!=EOF){
if(!n) break;
creat(1,n,1);
for(int i=0;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
upd(a,b,1);
}
// for(int i=1;i<=20;i++) cout<<lazy[i]<<" ";
query(1);
printf("\n");
}
}