一般的树状数组对于可减信息可以实现单点修改+区间查询,如果套用差分,可以实现区间修改+单点查询。
同时实现区间修改和查询的方法
设要维护的序列(a),差分数组(d_i = a_i - a_{i-1})
要求([1, x])区间的和:
[egin{aligned}
query(x) &=
sum_{i=1}^x a_i \&= sum_{i=1}^x sum_{j=1}^i d_i \
&= sum_{i=1}^x (x-i+1)d_i
end{aligned}
]
维护一个序列(ds_i = (i-1)d_i)
则和为(x sum_{i=1}^x d_i - sum_{i=1}^xds_i)
Code
不要对这个压行!虽然每行代码都很短,但可能会出事!
很可能原来写的int
改long long
就会忘改
ll d[Len2], ds[Len2];
int BITLen;
inline void modifyT(ll *t, int p, ll x){
for(; p<=BITLen; p += p & -p) t[p] += x;
}
inline ll queryT(ll *t, int p){
ll r = 0;
for(; p; p ^= (p & -p)) r += t[p];
return r;
}
inline void modify(int p, ll x){
if(p <= BITLen)
modifyT(d, p, x), modifyT(ds, p, x * (p - 1));
}
inline ll query(int p){
if(p < 0) return 0;
p = min(p, BITLen);
return p * queryT(d, p) - queryT(ds, p);
}
打一些题很方便,比线段树友好多了,常数也小