题目:我是超链接
题解:
每次添加一个线段,求在一个区间内能看到多少条线段。我们考虑一下什么样的线段看不见------终点在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));
}
}