Re
"Problem Introduction"
For the simple problem of interval modification and interval query, it is really not worth hitting a bunch of line-segment trees today to introduce a tree array of interval query + interval modification
"Some Basics"
The basic knowledge of the tree array is no longer introduced, please own Baidu
We assume that Sigma (R,i) represents the first I term of the r array and that the complexity of the call is log2 (i)
Set the original array is a[n], Difference fractional group C[n],c[i]=a[i]-a[i-1], then obviously A[i]=sigma (c,i), if you want to modify A[i] to A[j] (such as +v), just make C[i]+=v,c[j+1]-=v
"The main content of today"
We can achieve the Nlogn time "single-point modification, Interval query", "interval modification, single-point query", in fact, the latter is a deformation of the former, to understand the nature of the tree array is "single-point modification, interval query"
How to achieve "interval modification, interval query"?
Observe the formula:
A[1]+a[2]+...+a[n]
= (C[1]) + (c[1]+c[2]) + ... + (C[1]+c[2]+...+c[n])
= N*c[1] + (n-1) *c[2] + ... +c[n]
= n * (C[1]+c[2]+...+c[n])-(0*c[1]+1*c[2]+...+ (n-1) *c[n]) (Formula ①)
Then we'll maintain an array c2[n], where c2[i] = (i-1) *c[i]
Whenever you modify C, you modify the C2, so that the complexity does not change
So
Formula ①
=n*sigma (C,n)-Sigma (C2,n)
So we did it. Complete the interval and query in O (LOGN) time
A good thing is that the constant of the tree array is much smaller than the data structure of other nlogn, in fact it is much smaller than the Nlogn, plus it is short code, is the weapon of the OI
1#include <cstdio>2#include <cstring>3#include <iostream>4#include <algorithm>5 #defineN 200100*86 using namespacestd;7typedefLong Longll;8 intn,m;9 ll A[n],c1[n],c2[n];Ten structio{ One Charop[1<< -],*s; A io () - { -Fread (S=op,1,1<< -, stdin); the } -InlineintRead () - { -Registerintu=0; + while(*s< -) s++; - while(*s> +) u=u*Ten+*s++- -; + returnu; A } at }ip; - #defineRead Ip.read -InlineintLowbit (intx) {returnx& (-x);} - voidAdd (ll *r,intPos, ll v) - { - for(;p os<=n;pos+=lowbit (POS)) r[pos]+=v; in } -ll Getsum (ll *r,intPOS) to { +ll re=0; - for(;p os>0;p Os-=lowbit (POS)) re+=R[pos]; the returnre; * } $LL Sigma (intR)Panax Notoginseng { -ll Sum1=r*getsum (c1,r), sum2=getsum (c2,r); the returnSum1-sum2; + } All query (intXinty) the { + returnSigma (Y)-sigma (X-1); - } $ intflag,x,y;ll K; $ intMain () - { -n=read (); the for(intI=1; i<=n;i++) - {Wuyia[i]=read (); theAdd (c1,i,a[i]-a[i-1]); -Add (C2,i, (i-1) * (a[i]-a[i-1])); Wu}m=read (); - for(intI=1; i<=m;i++) About { $flag=read (); - if(flag==1) - { -X=read (); Y=read (); k=read (); AAdd (c1,x,k); Add (c1,y+1,-k); +Add (C2,x, (X-1) *k); Add (c2,y+1, y* (-k)); the } - Else $ { theX=read (); y=read (); theprintf"%lld\n", query (x, y)); the } the } - return 0; in}
View Code
230ms the fastest Qaq
Tree-like array interval update/query