题意
在平面内有一条长度为n的线段(也算一条线段),上面有m条线段,问x到y之间有多少条线段。
思路
用cover统计当前区间有多少条线段,统计的时候我们先找到x到y这个区间所代表的节点,然后从这个节点往它的根结点去统计,因为cover可能不会下传到x到y这个区间里,而是到它的父节点上。
代码
#include<cstdio>
int n,m,x,y,ans,z,f;
struct tr{
int b,e,cover;
}tree[400001];
void creat(int p,int l,int r)
{
tree[p].b=l;
tree[p].e=r;
if (r-l>1)
{
int m=(l+r)>>1;
creat(2*p,l,m);
creat(2*p+1,m,r);
}
}
void insert(int p,int l,int r)
{
int m=(tree[p].b+tree[p].e)>>1;
if (tree[p].b==l&&tree[p].e==r) tree[p].cover++;
else if (r<=m) insert(2*p,l,r);
else if (l>=m) insert(2*p+1,l,r);
else
{
insert(2*p,l,m);
insert(2*p+1,m,r);
}
}
void count(int p,int l,int r)
{
int m=(tree[p].b+tree[p].e)>>1;
if (tree[p].b==l&&tree[p].e==r) f=p;//如果找到了这个区间就可以记录下这个点了
else if (r<=m) count(2*p,l,r);
else if (l>=m) count(2*p+1,l,r);
else
{
count(2*p,l,m);
count(2*p+1,m,r);
}
}
void an(int p)
{
while (p>0)
{
ans+=tree[p].cover;
p/=2;//一直往根节点统计
}
}
void init()
{
scanf("%d%d",&n,&m);
creat(1,1,n);
for (int i=1;i<=m;i++)
scanf("%d%d",&x,&y),insert(1,x,y);
scanf("%d%d",&x,&y);
count(1,x,y);//找出这个区间所代表的节点
an(f);//统计
printf("%d",ans);
}
int main()
{
init();
}