Fenwick tree [section modify, query interval]

Perhaps a better reading experience

Good thing, then you can not hit the tree line

Benpian assumed that the reader will be the most basic two Fenwick tree that area to change a single check and change the single area search

Thinking about how to maintain a range of values, think of the difference
of a fraction of the investigation group to do a prefix and get the value of each position
and then accumulate at the location of each interval is the value of a
formulaic speaking, is
set differential array is \ (c \)
the value of each position
\ (val_i = \ sum \ limits_
{j = 1} ^ ic_j \) an interval \ ([l, r] \ ) values
\ (s_ {l, r} = \ sum \ limits_ {i = l} ^ rval_i
\) is written in the form of a prefix and subtraction is
\ (s_ {l, r} = \ sum \ limits_ {i = 1} ^ rval_i- \ sum \ limits_ {i = 1} ^ { l-1} val_i \)

Not difficult to find, the value of a range of difference is actually an array of prefix and prefix and subtraction

In other words, as long as we maintain the prefix and prefix and can be used Fenwick tree maintenance intervals up
to consider how to maintain the prefix and prefix and
\ (s_p = \ sum \ limits_ {i = 1} ^ p \ sum \ limits_ { j = 1} ^ ic_j \)
consider each \ (C_J \) the number of occurrences can be obtained
\ (s_p = \ sum \ limits_ {i = 1} ^ p \ left (p-i + 1 \ right) c_i = \ left (p + 1 \ right ) \ sum \ limits_ {i = 1} ^ pc_i- \ sum \ limits_ {i = 1} ^ pi * c_i \)

After simple derivation as above, as long as we maintain \ (\ sum \ limits_ {i = 1} ^ pc_i \) and \ (\ sum \ limits_ {i = 1} ^ pi * c_i \) two things can be a
former is the difference array, which we index as long as the difference in the maintenance of the array multiplied by the corresponding position to
these two things we can maintain a single point of inquiry modify the interval by the same method Fenwick tree maintenance

int c1[maxn],c2[maxn];
int lbt (int x){ return x & -x; }
void modify (int l,int r,int v)//维护差分数组
{
    ++r;
    for (int i=l;i<=n;i+=lbt(i))    c1[i]+=v,c2[i]+=l*v;
    for (int i=r;i<=n;i+=lbt(i))    c1[i]-=v,c2[i]-=r*v;
}

These two very beginning I did not understand, not to say that good maintenance \ (i * c_i \) it, it becomes time to write out how \ (l * v \) and \ (r * v \) up
if you have such doubts, they did not play too long to explain the principles principle Fenwick tree or tree-like array of thought you have forgotten Fenwick tree of the

This thing is to maintain a differential array , rather than the prefix and the differential array!

For queries

int query (int l,int r)
{
    int res=0;
    for (int i=r;i;i-=lbt(i))   res+=(r+1)*c1[i]-c2[i];
    for (int i=l-1;i;i-=lbt(i)) res-=l*c1[i]-c2[i];
    return res;
}

If not quite understand where to put it or there is an error, please correct me
if you like, you may wish to point a collection of praise about it

Guess you like

Origin www.cnblogs.com/Morning-Glory/p/11779230.html