问题描述
n 个木桩排成一排,从左到右依次编号为 1,2,3…n。每次给定 2 个整数 a,b(a≤b),蒜头君便骑上他的电动车从木桩 a 开始到木桩 b 依次给每个木桩涂一次颜色。但是 n 次以后 lele 已经忘记了第 i 个木桩已经涂过几次颜色了,你能帮他算出每个木桩被涂过几次颜色吗?
输入格式
第一行是一个整数 n(n≤100000)。
接下来的 n 行,每行包括两个整数 a, b (1≤a≤b≤n)。
输出格式
n 个整数,第 i 个数代表第 i 个木桩总共被涂色的次数。
样例输入
3
1 1
1 2
1 3
样例输出
3 2 1
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N=(1e5)+50;
int s[MAX_N*4];
int lazy[MAX_N*4];
void up(int p){
s[p]=s[p*2]+s[p*2+1];
return;
}
void down(int p,int l,int r){
if(lazy[p]){
int mid=(l+r)/2;
s[p*2]+=lazy[p]*(mid-l+1);
s[p*2+1]+=lazy[p]*(r-mid);
lazy[p*2]+=lazy[p];
lazy[p*2+1]+=lazy[p];
lazy[p]=0;
}
return;
}
void molify(int p,int l,int r,int x,int y,int v){
if(x<=l&&y>=r){
s[p]+=v*(r-l+1);
lazy[p]+=v;
return;
}
down(p,l,r);
int mid=(l+r)/2;
if(x<=mid)molify(p*2,l,mid,x,y,v);
if(y>mid)molify(p*2+1,mid+1,r,x,y,v);
up(p);
return;
}
int query(int p,int l,int r,int x,int y){
if(x<=l&&y>=r){
return s[p];
}
down(p,l,r);
int mid=(l+r)/2;
int res=0;
if(x<=mid)res+=query(p*2,l,mid,x,y);
if(y>mid)res+=query(p*2+1,mid+1,r,x,y);
return res;
}
int main(){
int n;
cin>>n;
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
molify(1,1,n,a,b,1);
}
for(int i=1;i<=n;i++){
cout<<query(1,1,n,i,i);
if(i!=n)cout<<" ";
}
return 0;
}