P1473 校门外的树3

时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,读入l,r表示在l~r之间种上的一种树
K=2,读入l,r表示询问l~r之间能见到多少种树
(l,r>0)

输入格式

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

输出格式

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

测试样例1

输入

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

输出


2

备注

范围:20%的数据保证,n,m<=100
      60%的数据保证,n <=1000,m<=50000
      100%的数据保证,n,m<=50000
注意:树是可以重叠的,比如1号位置上可以种多种树

树状数组

开两个树状数组,一个记录起点,一个记录终点。

一个区间内树的种类=起点小于区间末尾的树的种数-终点小于区间头的树的种数

(也可以用线段树)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,m;
 6 int t[2][50010];
 7 void add(int a,int x,int v){
 8     while(x<=n){
 9         t[a][x]+=v;
10         x+=x&-x;
11     }
12     return;
13 }
14 int smm(int a,int x){
15     int res=0;
16     while(x){
17         res+=t[a][x];
18         x-=x&-x;
19     }
20     return res;
21 }
22 int main(){
23     scanf("%d%d",&n,&m);
24     int i,j,op,x,y;
25     while(m--){
26         scanf("%d%d%d",&op,&x,&y);
27         if(op==1){
28             add(0,x,1);
29             add(1,y,1);
30         }
31         else{
32             int ans=smm(0,y)-smm(1,x-1);
33             printf("%d
",ans);
34         }
35     }
36     return 0;
37 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6341563.html