题目链接:【HDU 1556】
这个题目还是不用线段树比较简单一点
一段被刷过一次,也就是说这一段都要+1
在开头部分加上1,末尾后一位-1,用数组记录
举个例子:
3
1 1
1 2
1 3
一开始数组s[ ] 清零
最终s[ 1 ] = 3 s[ 2 ] = 2 s[ 3 ]=-1
累加,边加边输出
<span style="font-size:14px;">#include <cstdio>
#include <cstring>
int p[100006];
int main()
{
int n;
while(~scanf("%d",&n),n)
{
int a,b;
memset(p,0,sizeof(p));
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
p[a]++;
p[b+1]--;
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans+=p[i];
if(i==n) printf("%d\n",ans);
else printf("%d ",ans);
}
}
return 0;
}</span>
线段树:
<span style="font-size:14px;">#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
#define inf 100005
int ans;
struct node
{
int add;
}p[inf<<2];
void update(int n,int l,int r,int a,int b)
{
if(l==a && b==r)
{
p[n].add++;
return;
}
int mid = (l+r)>>1;
if(b<=mid) update(n<<1,l,mid,a,b);
else if(a>mid) update((n<<1)+1,mid+1,r,a,b);
else
{
update(n<<1,l,mid,a,mid);
update((n<<1)+1,mid+1,r,mid+1,b);
}
}
void query(int n,int l,int r,int u)
{
if(u>=l && u<=r)
{
ans+=p[n].add;
}
if(l==r) return;
int mid = (l+r)>>1;
if(u<=mid) query(n<<1,l,mid,u);
else query((n<<1)+1,mid+1,r,u);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF,n)
{
memset(p,0,sizeof(p));
int a,b;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
update(1,1,n,a,b);
}
for(int i=1;i<=n;i++)
{
ans=0;
query(1,1,n,i);
if(i==n) printf("%d\n",ans);
else printf("%d ",ans);
}
}
return 0;
}</span>