【tyvj1473】校门外的树3

题目:我是超链接

题解:

每次添加一个线段,求在一个区间内能看到多少条线段。我们考虑一下什么样的线段看不见------终点在x以前的,起点在y以后的......

我们只需要用总数-看不到的数量就是ans,那么只需要记录每个点起点和终点的位置就ok-------单点修改,区间查询

注意好好考虑边界,如果x-1=0那么就是左边不用搜了,反正不会有看不到的线段。。。

代码:

#include 
#define N 200005
using namespace std;
int ll[N],rr[N],n,m,sum;
void updata(int now,int l,int r,int x,int id)
{
	if (l==r) {if (id==1) ll[now]++;else rr[now]++;return;}
	int mid=(l+r)>>1;
	if (x<=mid) updata(now<<1,l,mid,x,id);
	else updata(now<<1|1,mid+1,r,x,id);
	if (id==1) ll[now]=ll[now<<1]+ll[now<<1|1];else rr[now]=rr[now<<1]+rr[now<<1|1];
}
int qurry(int now,int l,int r,int lrange,int rrange)
{
	if (lrange>rrange) return 0;
	if (lrange<=l && rrange>=r) return rr[now];
	int mid=(l+r)>>1,ans=0;
	if (lrange<=mid) ans+=qurry(now<<1,l,mid,lrange,rrange);
	if (rrange>mid) ans+=qurry(now<<1|1,mid+1,r,lrange,rrange);
	return ans;
}
int qurry2(int now,int l,int r,int lrange,int rrange)
{
	if (lrange>rrange) return 0;
	if (lrange<=l && rrange>=r) return ll[now];
	int mid=(l+r)>>1,ans=0;
	if (lrange<=mid) ans+=qurry2(now<<1,l,mid,lrange,rrange);
	if (rrange>mid) ans+=qurry2(now<<1|1,mid+1,r,lrange,rrange);
	return ans;
}
int main()
{
	int i;
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++) 
	{
		int id,x,y;
		scanf("%d%d%d",&id,&x,&y);
		if (id==1)
		{
			sum++;
			updata(1,1,n,x,1);
			updata(1,1,n,y,2);
		}
		else printf("%d\n",sum-qurry(1,1,n,1,x-1)-qurry2(1,1,n,y+1,n));
	}  
}


你可能感兴趣的:(线段树)