分类目录归档:树状数组

洛谷 P1972 [SDOI2009]HH的项链

参考题解:https://www.luogu.org/blog/skylee/solution-p1972

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int arr[500005];
int c[500000];
int last[1000001];
int flag=0;
struct question{
    int id,l,r,ans;
    bool operator < (const question& q2) const{
        if(flag==0)return r<q2.r;
        else return id<q2.id;
    }
}qs[200005];
inline int lowbit(int i){
    return i&(-i);
}
int query(int x){
    int sum=0;
    while(x>0){
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
void update(int i,int v){
    while(i<=n){
        c[i]+=v;
        i+=lowbit(i);
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>qs[i].l>>qs[i].r;
        qs[i].id=i;
    }
    sort(qs+1,qs+m+1);
    int ptr=1;
    for(int i=1;i<=m;i++){
        for(;ptr<=qs[i].r;ptr++){
            if(last[arr[ptr]]!=0)update(last[arr[ptr]],-1);
            update(last[arr[ptr]]=ptr,1);
        }
        qs[i].ans=query(qs[i].r)-query(qs[i].l-1);
    }
    flag=1;
    sort(qs+1,qs+m+1);
    for(int i=1;i<=m;i++){
        cout<<qs[i].ans<<endl;
    }
}

洛谷 P3368 【模板】树状数组 2

看起来实际上也挺好做的,就是只要把树状数组维护的对象改成原序列的差分数组即可。这样每次树状数组所谓的query求1到n的前缀和也就变成了就单点n的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream>
#include<cstring>
using namespace std;
struct BTA{//Update Section,Query Single Point
    const static int MAX=500000;
    int C[MAX+5];
    BTA(){
        memset(C,0,sizeof(C));
    }
    int lowbit(int i){
        return i&(-i);
    }
    int query(int x){
        int sum=0;
        while(x>0){
            sum+=C[x];
            x-=lowbit(x);
        }
        return sum;
    }
    void update(int i,int v){
        while(i<=MAX){
            C[i]+=v;
            i+=lowbit(i);
        }
    }
    void updateSection(int l,int r,int v){
        update(l,v);
        update(r+1,-v);
    }
}TA;
int n,m;
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int v;
        cin>>v;
        TA.updateSection(i,i,v);
    }
    for(int i=1;i<=m;i++){
        int op,v1,v2,v3;
        cin>>op;
        if(op==1){
            cin>>v1>>v2>>v3;
            TA.updateSection(v1,v2,v3);
        }
        else{
            cin>>v1;
                cout<<TA.query(v1)<<endl;
        }
    }
}

洛谷 【模板】树状数组 1

题号:3374

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
using namespace std;
struct treearray{
    const static int MAX=500005;
    int C[MAX];
    treearray(){
        memset(C,0,sizeof(C));
    }
    int lowbit(int i){
        return i&(-i);
    }
    void update(int i,int n){
        while(i<=MAX){
            C[i]+=n;
            i+=lowbit(i);
        }
    }
    int sum(int k){
        int sum=0;
        while(k>0){
            sum+=C[k];
            k-=lowbit(k);
        }
        return sum;
    }
}ta;
int main(){
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int t;
        cin>>t;
        ta.update(i,t);
    }
    for(int i=1;i<=m;i++){
        int p1,p2,p3;
        cin>>p1>>p2>>p3;
        switch(p1){
        case 1:
            ta.update(p2,p3);
            break;
        case 2:
            cout<<(ta.sum(p3)-ta.sum(p2-1))<<endl;
            break;
        }
    }
}