zoukankan      html  css  js  c++  java
  • Ryuji doesn't want to study (树状数组)

    【传送门】:https://nanti.jisuanke.com/t/31460

    【题意】给定一个数组a[N],有两种操作,

    操作1,给定 l , r,  查询a[l]×L+a[l+1]×(L1)++a[r1]×2+a[r]的值

    (L is the length of [ llrr ] that equals to r - l + 1rl+1).

    操作2, 给定x,y, 使a[x] = y

    有N个数据,M种操作,对于每个操作1输出计算结果。

    【题解】很容易想出来是树状数组类型的题目。但是直接计算不好计算,需要构造合适的树状数组的原数组。这个原数组并不是单纯的a[N]

    考虑题目要求的序列,将其变形:

    这样我们可以构造并维护两个数组的树状数组,一个是a[i]的树状数组C1[i],一个是 a[i]*i的树状数组C2[i]。

    注意这里是修改值而不是增加值,所以增加的是“新值与旧值得差”,并且要注意把原数组a[i]的值重新赋值。

    【AC代码】

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5+10; 
    ll a[maxn];
    int n,m;
    ll c1[maxn];
    ll c2[maxn];
    void init(){
        memset(a , 0 , sizeof a);
        memset(c1 , 0 , sizeof c1);
        memset(c2 , 0 , sizeof c2);
    }
    int lowbit(int x){
        return x & (-x);
    }
    
    ll query1(int x){
        ll ans = 0;
        while(x > 0){
            ans += c1[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void add1(int x , ll val){
        while(x <= n){
            c1[x] += val;
            x += lowbit(x);
        }
    }
    ll query2(int x){
        ll ans = 0;
        while(x > 0){
            ans += c2[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void add2(int x , ll val){
        while(x <= n){
            c2[x] += val;
            x += lowbit(x);
        }
    }
    
    
    int main(){
        while(cin>>n>>m){
            init();
            for(int i=1; i<=n; i++){
                cin>>a[i];
                add1(i , a[i]);
                add2(i , i*a[i]);
                //cout<<c1[i]<<" "<<c2[i]<<endl;
            }
            ll aa,bb,cc;
            for(int i=1; i<=m; i++){
                cin>>aa>>bb>>cc;
                if(aa == 1){
                    cout<<(cc+1)*( query1(cc) - query1(bb-1) ) - (query2(cc) - query2(bb-1))<<endl;
                }
                else{
                    add1(bb , cc - a[bb] );
                    add2(bb , bb*cc - bb*a[bb] );
                    a[bb] = cc;
                }
            }
            
        }
        return 0;
    }
    View Code
  • 相关阅读:
    UNIX高级环境编程(2)FIle I/O - 原子操作、共享文件描述符和I/O控制函数
    UNIX高级环境编程(1)File I/O
    排序算法(2) 堆排序 C++实现
    加深一下BlockingQueue的认识
    测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
    java中的锁
    Http状态码之:301、302重定向
    学点HTTP知识
    java中的字符串相关知识整理
    在Openfire上弄一个简单的推送系统
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9624416.html
Copyright © 2011-2022 走看看