题目
链接:https://ac.nowcoder.com/acm/contest/1108/H
来源:牛客网
Bobo 精通数据结构!他想维护一个线段的集合 S。初始时,S 为空。他会依次进行 q 次操作,操作有 2 种。
* 类型 1:给出 l, r,向集合 S 中插入线段 [l, r].
* 类型 2:给出 l, r,询问满足 [x,y]∈S[x, y] 且 x≤l≤r≤y 的线段 [x, y] 数量。
帮 Bobo 求出每次询问的答案。
数据组数不超过10,1<=n,q<=1e5,
保证对于类型2的询问[l,r]区间长度不超过2
思路来源
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=41349100
题解
用起点的左端点小于等于l的线段减去右端点小于等于r-1的线段即可
计数还是太菜
代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,q,op,l,r;
int a[N],b[N],ans;
void add(int *tr,int x,int v)
{
for(int i=x;i<=n;i+=i&-i)
tr[i]+=v;
}
int sum(int *tr,int x)
{
int ans=0;
for(int i=x;i>0;i-=i&-i)
ans+=tr[i];
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
for(int i=1;i<=n;++i)
a[i]=b[i]=0;
for(int i=1;i<=q;++i)
{
scanf("%d%d%d",&op,&l,&r);
if(op==1)add(a,l,1),add(b,r,1);
else printf("%d\n",sum(a,l)-sum(b,r-1));
}
}
return 0;
}