http://acm.hdu.edu.cn/showproblem.php?pid=1556
感觉对线段树还不是很熟练,通过此题学到这种结构体设置方法(线段树的关键就是在结构体的设置),如果对区间内所有元素做同样操作,只需对线段树上对应区间操作即可。否则如果对所有元素操作,会超时,但进行query()要计算到叶子节点。
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100000
using namespace std;
struct node
{
int l,r;
int count;
int mid()
{
return (l+r)>>1;
}
};
node tree[N*3];
void buildtree(int l,int r,int pos)
{
tree[pos].l=l;
tree[pos].r=r;
tree[pos].count=0;
if(l==r)
return ;
buildtree(l,tree[pos].mid(),pos<<1);
buildtree(tree[pos].mid()+1,r,(pos<<1)+1);
}
void update(int l,int r,int pos)
{
if(tree[pos].l==l&&tree[pos].r==r)
{
tree[pos].count++;
return ;
}
if(r<=tree[pos].mid())
{
update(l,r,pos<<1);
}
else if(l>tree[pos].mid())
{
update(l,r,(pos<<1)+1);
}
else
{
update(l,tree[pos].mid(),pos<<1);
update(tree[pos].mid()+1,r,(pos<<1)+1);
}
}
void query(int pos,int sum)
{
if(tree[pos].l==tree[pos].r)
{
if(tree[pos].l==1)
printf("%d",tree[pos].count+sum);
else
printf(" %d",tree[pos].count+sum);
return ;
}
query(pos<<1,tree[pos].count+sum);
query((pos<<1)+1,tree[pos].count+sum);
}
int main()
{
int n;
while(scanf("%d",&n),n)
{
int i,t1,t2;
memset(tree,0,sizeof(tree));
buildtree(1,n,1);
for(i=0;i<n;i++)
{
scanf("%d%d",&t1,&t2);
update(t1,t2,1);
}
query(1,0);
printf("\n");
}
}