树状数组基础用法模板

默写回顾了一下板子。
1、树状数组的单点查询和单点修改模板:

int tr[N]; 

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

// 在x位置上面增加c
void add(int x, int c) 
{
    for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;  
}

// 求到x的前缀和
int sum(int x) 
{
    int res = 0; 
    for(int i = x; i; i -= lowbit(i)) 
        res += tr[i]; 
    return res; 
}

2、树状数组的区间修改和区间查询:
 

int tr1[N], tr2[N]; 

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

void add(int tr[], int x, int c) 
{
    for(int i = x; i <= n; i += lowbit(i)) tr[i] += c; 
}

int sum(int tr[], int x) 
{
    int res = 0; 
    for(int i = x; i; i -= lowbit(i)) res += tr[i]; 
    return res; 
}

int get(int l) 
{
    return (l + 1) * sum(tr1, l) - sum(tr2, l);  
}
signed main() 
{
    scanf("%lld%lld", &n, &m); 
    
    for(int i = 1; i <= n; i ++ ) 
        scanf("%lld", &a[i]); 
    
    for(int i = 1; i <= n; i ++ ) 
        add(tr1, i, a[i] - a[i - 1]), add(tr2, i, i * (a[i] - a[i - 1])); 
        
    while(m --) 
    {
        char op[2]; 
        int l, r, d; 
        scanf("%s%lld%lld", op, &l, &r); 
        if(*op == 'C')  // 区间修改
        {
            scanf("%lld", &d); 
            add(tr1, l, d), add(tr1, r + 1, -d); 
            add(tr2, l, l * d), add(tr2, r + 1, -(r + 1) * d); 
        }
        else 
        {
            // 区间查询 
            printf("%lld\n", get(r) - get(l - 1)); 
        }
    }
    
    return 0; 
}

你可能感兴趣的:(算法,c++)