题目
题目描述
面对蚂蚁们的疯狂进攻,小FF的Tower defence宣告失败……人类被蚂蚁们逼到了Greed Island上的一个海湾。现在,小FF的后方是一望无际的大海, 前方是变异了的超级蚂蚁。 小FF还有大好前程,他可不想命丧于此, 于是他派遣手下最后一批改造SCV布置地雷以阻挡蚂蚁们的进攻。
小FF最后一道防线是一条长度为N的战壕, 小FF拥有无数多种地雷,而SCV每次可以在
[
L
,
R
]
[ L , R ]
[L,R]区间埋放同一种不同于之前已经埋放的地雷。 由于情况已经十万火急,小FF在某些时候可能会询问你在
[
L
′
,
R
′
]
[ L' , R']
[L′,R′] 区间内有多少种不同的地雷, 他希望你能尽快的给予答复。
输入输出格式:
输入格式
第一行为两个整数
n
n
n和
m
m
m
n
n
n表示防线长度,
m
m
m表示SCV布雷次数及小FF询问的次数总和。
接下来有m行, 每行三个整数
Q
,
L
,
R
Q,L , R
Q,L,R;若
Q
=
1
Q=1
Q=1则表示SCV在[L,R]这段区间布上一种地雷,若
Q
=
2
Q=2
Q=2则表示小FF询问当前[L,R]区间总共有多少种地雷。
输出格式
对于小FF的每次询问,输出一个答案(单独一行),表示当前区间地雷总数。
输入输出样例
输入样例
5 4
1 1 3
2 2 5
1 2 4
2 3 5
输出样例
1
2
数据范围
对于30%的数据:
0
≤
n
,
m
≤
1000
0 \le n, m \le 1000
0≤n,m≤1000;
对于100%的数据:
0
≤
n
,
m
≤
1
0
5
0\le n, m \le10^5
0≤n,m≤105。
解析
求
L
L
L到
R
R
R之间有多少种地雷,因为放地雷都是按照区间放的,而且每次放的地雷都不相同,
那么只要用
1
1
1到
L
L
L的地雷种数(也就是从
1
1
1到
L
L
L开始放置地雷的个数)再减去
1
1
1到
R
−
1
R−1
R−1已经放置结束了的地雷(也就是放置地雷时的
R
R
R)种数就是答案了。
接下来就简单了,用两个树状数组维护两个前缀和就好了。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int q,l,r;
const int Maxn=100010;
int Ar1[Maxn],Ar2[Maxn];
int lowbit(int x)
{
return x&(-x);
}
void update1(int x)
{
while(x<=n)
{
Ar1[x]++;
x+=lowbit(x);
}
}
void update2(int x)
{
while(x<=n)
{
Ar2[x]++;
x+=lowbit(x);
}
}
int ask1(int x)
{
int ans=0;
while(x)
{
ans+=Ar1[x];
x-=lowbit(x);
}
return ans;
}
int ask2(int x)
{
int ans=0;
while(x)
{
ans+=Ar2[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&q,&l,&r);
if(q==1)
{
update1(l);
update2(r);
}else{
printf("%d\n",ask1(r)-ask2(l-1));
}
}
return 0;
}
好了,我今天讲的内容结束了。您有什么问题可以来问我,我的blog有问题您也可以来提醒我改正