E - Sum of Subarrays Editorial
by
physics0523
過剰な \(\log\) が付きますが、 segment tree で解くこともできます。
区間和 \(\sum_{k=l}^{r} A_k\) を累積和を使って \(B_{r+1} - B_{l}\) という形に変形すると、 \(B\) の連続する区間を segment tree に乗せやすくなります。
segtree のモノイドとして、以下のものを持っています。以下の情報があれば求解するのに十分です。
- 区間内の \(B_k\) の総和 \(val\)
- 区間の長さ \(len\)
- 区間内での答え \(res\)
実装例 (C++):
#include<bits/stdc++.h>
#include<atcoder/all>
using namespace std;
using namespace atcoder;
using ll=long long;
typedef struct{
ll val;
ll len;
ll res;
}S;
S e(){ return {0,0,0}; }
S op(S l,S r){
S res;
res.val=l.val+r.val;
res.len=l.len+r.len;
res.res=l.res+r.res;
res.res+=l.len*r.val;
res.res-=l.val*r.len;
return res;
}
int main(){
ll n,q;
cin >> n >> q;
vector<ll> a(n);
for(auto &nx : a){cin >> nx;}
vector<S> ini(n+1);
S cur={0,1,0};
ini[0]=cur;
for(ll i=1;i<=n;i++){
cur.val+=a[i-1];
ini[i]=cur;
}
segtree<S,op,e> seg(ini);
vector<ll> res;
while(q>0){
q--;
ll l,r;
cin >> l >> r;
l--;
cout << seg.prod(l,r+1).res << "\n";
}
return 0;
}
posted:
last update: