题意:
第一种操作是每次在一个区间布置添加一种地雷,第二种操作求指定区间地雷种类。
思路:
利用前缀和的思想,[L,R]之间的地雷种数等于1~R之间的地雷种数减去 1~R之间那些没有在[L,R]之间的种数。
1到R之间的地雷种数就是1~R之间的左端点个数。
没有布置到[L,R]之间的,就是在1~L-1里就已经布置结束的个数,也就是1到L-1之间的右端点个数。
所以就用树状数组维护前缀的左端点与右端点个数即可。布置一次地雷在左端点处左端点数加1,右端点处右端点数加1。
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
int c[5][maxn];
int n,m;
int lowbit(int x)
{
return x&(-x);
}
int sum(int x,int op)
{
int res=0;
while(x>0)
{
res+=c[op][x];
x-=lowbit(x);
}
return res;
}
void add(int x,int d,int op)
{
while(x<=n)
{
c[op][x]+=d;
x+=lowbit(x);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
int q,l,r;
scanf("%d%d%d",&q,&l,&r);
if(q==1)
{
add(l,1,1);//1代表左端点个数,2代表右端点个数
add(r,1,2);
}
else if(q==2)
printf("%d\n",sum(r,1)-sum(l-1,2));
}
return 0;
/*树状数组前缀和的思想。[L,R]之间的地雷种数等于1~R之间的地雷种数(1~R之间左端点的个数)减去1~R之间那些没有在[L,R]之间出现的种数*/
/*没有布置到[L,R]之间出现的种数就是在1~L-1之间就布置结束的种数,也就是1~L-1之间右端点的个数*/
}