统计和 luogu P2068 树状数组和线段树练手

洛谷AC传送门

树状数组和线段树的练手:

树状数组:

#include <bits/stdc++.h>
using namespace std;
#define N 100010

inline int read(){
    int x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == '-') s = -1;
        c = getchar();
    }
    while(isdigit(c)){
        x = x * 10 + (c ^ '0');
        c = getchar();
    } 
    return x * s;
}

int n, m;
int tree[N];

inline int lowbit(int x){
    return x & (-x);
}

void add(int x, int k){
    for(register int i = x; i <= n; i += lowbit(i))
        tree[i] += k;
    return ;
}

int query(int x){
    int sum = 0;
    for(register int i = x; i; i -= lowbit(i)){
        sum += tree[i];
    }
    return sum;
}

int main(){
    n = read(), m = read();
    while(m--){
        char c;
        cin >> c;
        if(c == 'x'){
            int a = read(), k = read();
            add(a, k);
        }
        else if(c == 'y'){
            int a = read(), b = read();
            printf("%d
", query(b) - query(a - 1));
        }
    }
    return 0;    
}

线段树:

#include <bits/stdc++.h>
using namespace std;
#define N 100010

inline int read(){
    int x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == '-') s = -1;
        c = getchar();
    }
    while(isdigit(c)){
        x = x * 10 + (c ^ '0');
        c = getchar();
    } 
    return x * s;
}

struct tree{
    int add, w;
} t[N << 2];

inline void pushup(int o){
    t[o].w = t[o << 1].w + t[o << 1 | 1].w;
    return ;
}

inline void pushdown(int o, int l, int r){
    int mid = l + r >> 1;
    t[o << 1].add += t[o].add;
    t[o << 1 | 1].add += t[o].add;
    t[o << 1].w += t[o].add * (mid - l + 1);
    t[o << 1 | 1].w += t[o].add * (r - mid - 1 + 1);
    t[o].add = 0;
    return ; 
}

void build(int o, int l, int r){
    if(l == r){
        t[o].w = 0;
        return ;
    }
    int mid = l + r >> 1;
    build(o << 1, l, mid);
    build(o << 1 | 1, mid + 1, r);
    pushup(o);
    return ;
}

void update(int o, int l, int r, int x, int k){
    if(l > x || r < x) return ;
    if(l == r && l == x){
        t[o].w += k;
        return ;
    }
    pushdown(o, l, r);
    int mid = l + r >> 1;
    update(o << 1, l, mid, x, k);
    update(o << 1 | 1, mid + 1, r, x, k);
    pushup(o);
    return ;
}

int query(int o, int l, int r, int in, int end){
    if(l > end || r < in) return 0;
    if(l >= in && r <= end) return t[o].w;
    int mid = l + r >> 1;
    pushdown(o, l, r);
    return query(o << 1, l, mid, in, end) + query(o << 1 | 1, mid + 1, r, in, end);
}

int main(){
    int n = read(), m = read();
    build(1, 1, n);
    while(m--){
        char c;
        cin >> c;
        int x, y;
        switch(c){
            case 'x':
                x = read(), y = read();
                update(1, 1, n, x, y);
                break;
            case 'y':
                x = read(), y = read();
                cout << query(1, 1, n, x, y) << endl;
                break;
            }
    }
    return 0;
}

 

原文地址:https://www.cnblogs.com/wondering-world/p/13340735.html