P2184 貪婪大陸

題目連接

P2184 貪婪大陸數組

思路

樹狀數組的模板題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;
}
相關文章
相關標籤/搜索