题目链接
描述
校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,K=1,读入l、r表示在区间[l,r]中种上一种树,每次操作种的树的种类都不同
K=2,读入l,r表示询问l~r之间能见到多少种树
(l,r>0)
格式
输入格式
第一行n,m表示道路总长为n,共有m个操作
接下来m行为m个操作
输出格式
对于每个k=2输出一个答案
样例1
样例输入1
5 4
1 1 3
2 2 5
1 2 4
2 3 5
样例输出1
1
2
Let us 分析一下样例:
首先,
有五个坑可以装树:
x x x x x
然后,我们执行第一个操作::在1~3号坑种树一;
(x x x) x x
括号括住的内容就是第一次种树的范围;
接下来我们进行第二次操作,输出2~5号坑,直接输出1,就不需要演示了。。。
第三次,输入,这次是在2~4里面种树(为了方便,我们把第二次输入表示成中括号):
(x [ x x) x] x
然后我们再来第四步:
输出3~5号坑:很容易发现,这几个坑里有两种树;
让后我们神奇的发现:
所谓l~r号坑中的树,其实就是在坑中不同括号的数量;
那么我们只需要写一个统计的代码即可:
#include <cstdio>
int a[50005],n,m;
long long bit[50005][2];
int Lowbit(int x){
return x&(-x);
}
void HHup(int x,int k,int f){
for(int i=x;i<=n;i+=Lowbit(i))
bit[i][f]+=k;
return ;
}
long long HHsum(int x1,int f){
long long ans=0;
for(int i=x1;i>=1;i-=Lowbit(i)){
ans+=bit[i][f];
}
return ans;
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int pd;
scanf("%d",&pd);
if(pd==1){
int l,r;
scanf("%d%d",&l,&r);
HHup(l,1,0);
HHup(r,1,1);
}
else{
int l,r;
scanf("%d%d",&l,&r);
long long ans1=HHsum(r,0);
long long ans2=HHsum(l-1,1);
printf("%lld\n",ans1-ans2);
}
}
return 0;
}