樹狀數組的模板題spa
1.只要一個區間的開頭在一個節點$i$的左邊,那麼這個區間包含在區間$1~i$中。code
2.只要一個區間的尾部在一個節點$j$的左邊,那麼這個區間確定不屬於$j$以後的全部區間blog
因此咱們能夠搞兩個樹狀數組來作ci
$tree_{head}[i]$維護$i$以前的開頭數量get
$tree_{tail}[j]$維護$j$以前的結尾數量string
結合樣例能夠看出來$tree_{head}[j]-tree_{tail}[i]$即爲i-j之間的雷種類數it
樣例分析:io
5 4
1 1 3
2 2 5
1 2 4
2 3 5
1
2
假設要求2到3之間的雷種類數,能夠看出$tree_{tail}[1]=0$,$head_{tail}[3]=2$,
因此上述的結論成立
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<map> #include<string> #include<cstring> #define ll long long int #define lowbit(x) x & -x #define N 100000 using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int head_tree[N*2],tail_tree[N*2],n,m; void update_head(int x) { while(x<=n) { ++head_tree[x]; x+=lowbit(x); } } void update_tail(int x) { while(x<=n) { ++tail_tree[x]; x+=lowbit(x); } } int find_head(int x) { int res=0; while(x>0) { res+=head_tree[x]; x-=lowbit(x); } return res; } int find_tail(int x) { int res=0; while(x>0) { res+=tail_tree[x]; x-=lowbit(x); } return res; } int main() { cin>>n>>m; for(int i=1; i<=m; ++i) { int q,x,y; cin>>q>>x>>y; if(q==1) { update_head(x); update_tail(y); } else { cout<<find_head(y)-find_tail(x-1)<<"\n"; } } return 0; }