思路:本题只做区间更新,而不查询。方法很多,线段树是大才小用,代码长不说,在线地维护区间会TLE。故离线之。
线段树的做法:
<span style="font-size:14px;">#include <bits/stdc++.h>
using namespace std;
const int MAXN=100000+1000;
int st,en,tree[3*MAXN],ans[MAXN],ppp;
void update(int l,int r,int rt){
if(st<=l&&r<=en){
tree[rt]++;
return ;
}
int mid=(l+r)/2;
if(st<=mid)
update(l,mid,rt*2);
if(mid<en)
update(mid+1,r,rt*2+1);
return ;
}
void push_down(int rt){
tree[rt*2]+=tree[rt];
tree[rt*2+1]+=tree[rt];
}
void dfs(int l,int r,int rt){
if(l==r){
ans[++ppp]=tree[rt];return ;
}
push_down(rt);
int mid=(l+r)/2;
dfs(l,mid,rt*2);
dfs(mid+1,r,rt*2+1);
return ;
}
int main()
{
int n;
while(~scanf("%d",&n),n){
memset(tree,0,sizeof(tree));
for(int i=0;i<n;i++){
scanf("%d%d",&st,&en);
update(1,n,1);
}
ppp=-1;
dfs(1,n,1);
printf("%d",ans[0]);
for(int i=1;i<n;i++)
printf(" %d",ans[i]);
printf("\n");
}
}</span><span style="font-size:24px;">
</span>
离线扫描线的做法:
<span style="font-size:14px;">#include <bits/stdc++.h>
using namespace std;
const int MAXN=100000+1000;
int st,en,ans[MAXN];
int main()
{
int n;
while(cin>>n&&n){
memset(ans,0,sizeof(ans));
for(int i=0;i<n;i++){
scanf("%d%d",&st,&en);
ans[st]++;
ans[en+1]--;
}
printf("%d",ans[1]);
for(int i=2;i<=n;i++){
ans[i]+=ans[i-1];
printf(" %d",ans[i]);
}
cout<<endl;
}
}</span>