6566: 校门外的树2 树状数组

描述

 

 

校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两种操作:

K=1,读入 l,r 表示在 l 到 r 之间种上一种树,每次操作种的树的种类都不同;

K=2,读入 l,r 表示询问 l 到 r 之间有多少种树。

注意:每个位置都可以重复种树。

 

 

输入

 

 

第一行 n,m 表示道路总长为 n,共有 m 个操作;

接下来 m 行为 m 个操作。

对于 20% 的数据,1≤n,m≤100;

对于 60% 的数据,1≤n≤103,1≤m≤5×104 ;

对于 100% 的数据,1≤n,m≤5×104 ,保证 l,r>0。

 

 

输出

 

 

对于每个 k=2 输出一个答案。

 

 

样例输入

 

5 4
1 1 3
2 2 5
1 2 4
2 3 5

样例输出

1
2

树状数组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e4+10,inf = 0x3f3f3f3f;
int t1[N],t2[N];
int n,m,k,l,r;
int lowbit(int x)
{
    return x&(-x);
}
void updata1(int x,int v) //在x点加上v
{
    while(x<=n)
    {
        t1[x]+=v;
        x+=lowbit(x);
    }
} 
void updata2(int x,int v) //在x点加上v
{
    while(x<=n)
    {
        t2[x]+=v;
        x+=lowbit(x);
    }
} 
int sum1(int x)
{
    int res = 0;
    while(x>0)
    {
        res+=t1[x];
        x-=lowbit(x);
    }
    return res;
}
int sum2(int x)
{
    int res = 0;
    while(x>0)
    {
        res+=t2[x];
        x-=lowbit(x);
    }
    return res;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&k,&l,&r);
        if(k==1)updata1(l,1),updata2(r,1); //在l到r种树,所以要在l和r加上一个(和)
        else printf("%d\n",sum1(r)-sum2(l-1)); 
    }
     return 0;
}

 

posted @ 2023-05-31 21:08  CRt0729  阅读(23)  评论(0编辑  收藏  举报