校门外的树
Time Limit:10000MS Memory Limit:65536K
Case Time Limit:1000MS
Description
校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,读入l,r表示在l~r之间种上的一种树
K=2,读入l,r表示询问l~r之间能见到多少种树
(l,r>0)
Input
第一行n,m表示道路总长为n,共有m个操作
接下来m行为m个操作
Output
对于每个k=2输出一个答案
Sample Input
5 4
1 1 3
2 2 5
1 2 4
2 3 5
Sample Output
1
2
分析:
e m m m m m … … emmmmm…… emmmmm……还是模板题
1 x 1 x 1x为修改权值 2 x 2 x 2x为区间和 与 A p p l e T r e e Apple Tree AppleTree的操作差不多
这道题不用遍历树 所以较为 e a s y easy easy
但是要开两个树状数组 以及要分别写两个操作函数
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500005
using namespace std;
int n,m,a[N],c[N],qwq;
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
for(;x<=n;x+=lowbit(x)) //修改权值
c[x]++;
}
int find(int x)
{
int ans=0;
for(;x;x-=lowbit(x)) //求和
ans+=c[x];
return ans;
}
void update2(int x)
{
for(;x<=n;x+=lowbit(x)) //同理
a[x]++;
}
int find2(int x)
{
int ans=0;
for(;x;x-=lowbit(x)) //同理开两个
ans+=a[x];
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int X,l,r;
scanf("%d%d%d",&X,&l,&r);
if(X==1){
//判断操作
update(l);update2(r+1);
}else{
printf("%d\n",find(r)-find2(l)); //区间和
}
}
return 0;
}