[演算法設計與分析] 字首和
阿新 • • 發佈:2021-10-26
tag:樹狀陣列,差分,字首和
luogu P4868
&&學會使用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,constll 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; }