很早以前就看过线段树相关内容,但是感觉学得并不扎实,现在重新看下果然发现了很多问题,这题是属于线段树的入门题,帮助我很好的理解了线段树,时间上还待优化
#include <iostream>
using namespace std;
const int size = 100000;
struct STree
{
int l, r;
int cover;
}a[3*size+10];
void creat(int num, int l, int r)
{
a[num].l = l, a[num].r = r, a[num].cover = 0;
if (l == r)return ;
int mid = (l+r)>>1;
int p = num << 1;
creat(p, l, mid);
creat(p+1, mid+1, r);
}
int ans;
void insert(int num, int l, int r)
{
int tl = a[num].l, tr = a[num].r;
int mid = (tl + tr) >> 1;
int p = num << 1;
if (tl == l && tr == r){
a[num].cover ++;
}
else
if (r <= mid){
insert(p, l, r);
}
else
if (l > mid)
insert(p+1, l, r);
else {
insert(p, l, mid);
insert(p+1, mid+1, r);
}
}
int find1(int num, int l, int r)
{
int tl = a[num].l, tr = a[num].r;
if (tl == l && tr == r){
return a[num].cover;;
}
int sum = 0;
if (l >= tl && r <= tr){
int mid = (tl + tr)>>1;
int p = num << 1;
sum += a[num].cover;
if (l >= mid)sum += find1(p+1, l, r);
if (r <= mid)sum += find1(p, l, r);
}
return sum;
}
int main()
{
int n;
while (scanf("%d", &n) && n){
int a1, b1;
creat(1, 1, n);
for (int i = 0; i < n; i ++){
scanf("%d%d", &a1, &b1);
insert(1, a1, b1);
}
for (int i = 1; i <= n; i ++){
if (i!=1)printf(" ");
printf("%d", find1(1, i,i));
}
printf("\n");
}
return 0;
}