「一本通 4.1 例 3」校门外的树 (loj10115)

题目描述

原题来自:Vijos P1448

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

  • K=1,读入 l,r表示在 lr 之间种上一种树,每次操作种的树的种类都不同;
  • K=2,读入 l,r表示询问 lr之间有多少种树。

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

输入格式

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

输出格式

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

样例
样例输入
5 4
1 1 3
2 2 5
1 2 4
2 3 5
样例输出
1
2
数据范围与提示

对于 20% 的数据,1≤n,m≤100
对于 60% 的数据,1≤n≤10^3,1≤m≤5×10^4

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

 

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const long long maxn=50010;
int n, m;
inline void qread(int &x){
    x = 0;
    int ch = getchar();
    while(ch < '0' || ch > '9')        ch =getchar();
    while(ch >='0' && ch <= '9')    x = 10 * x + ch - 48, ch = getchar();
}
struct BItree{
    int data[maxn];
    BItree(){
        memset(data, 0, sizeof(data));
    }
    void add(int x){
        for(; x<=maxn-10; x += (x&-x))
            data[x]++;
    }
    int sum(int x){
        int ans = 0;
        for(; x; x -= (x&-x))
            ans += data[x];
        return ans;    
    }
};
int main(void)
{
    BItree left, right;
    qread(n), qread(m);
    while(m--){
        int x, y, z;
        qread(x), qread(y), qread(z);
        if(x-1){
            printf("%d\n", left.sum(z) - right.sum(y - 1));
        }else{
            left.add(y);
            right.add(z);
        }
    }
}

 

思路:

  建两个树状数组,其中一个存储从1-n区间左端点的数目,另一个存储1-n区间右端点的数目,则l-r内树的种数即为right(r) - left(l-1).

 

​​,保证 l,r>0l,r\gt 0l,r>0。3​​,1m5×104​​;
对于 100%100\%100% 的数据,1≤n,m≤5×1041\le n,m\le 5\times 10^41n,m5×104​​,保证 l,r>0l,r\gt 0l,r>0。

转载于:https://www.cnblogs.com/junk-yao-blog/p/9470876.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值