[算法设计与分析] 前缀和 (树状数组)
tag:树状数组,差分,前缀和
&&学会使用class类简化代码就很奈斯
// // main.cpp // 前缀和 // // Created by sylvia on 2021/10/25. // Copyright © 2021 apple. All rights reserved. // /* 将ss展开可得ssi=(i+1)sigma(i,j=1)aj - sigma(i,j=1)j*aj 所以可以维护两个树状数组sigma(i,j=1)aj 和sigma(i,j=1)j*aj 第一个传统建树modify(i,a[i]) 单点修改modify(i,x-a[i]) 后者建树和单点修改为modify(i,a[i]*i) 和 modify(i,(x-a[i])*i) */ #include<iostream> #include<cstdio> #include<algorithm> #include<string> using namespace std; typedef long long ll; const int MAXN=1e5+5; ll n,m; ll a[MAXN]; class BIT { private: ll tree[MAXN]; ll lowbit(const ll x){return x&(-x);} public: void modify(ll pos,const ll x) { for(;pos<=n;pos+=lowbit(pos)) tree[pos]+=x; } ll query(ll pos) { ll res=0; for(;pos;pos-=lowbit(pos)) res+=tree[pos]; return res; } }t1,t2;//简化代码 int main() { cin>>n>>m; for(ll i=1;i<=n;i++) cin>>a[i]; for(ll i=1;i<=n;i++) { t1.modify(i,a[i]); t2.modify(i,a[i]*i); } while(m--) { string s; cin>>s; if(s=="Modify") { ll pos,x; cin>>pos>>x; t1.modify(pos,x-a[pos]); t2.modify(pos,(x-a[pos])*pos); a[pos]=x; } if(s=="Query") { ll pos; cin>>pos; cout<<((pos+1)*t1.query(pos)-t2.query(pos))<<endl; } } return 0; }