樹狀陣列區間修改,單點查詢

2021-09-11 22:14:47 字數 1443 閱讀 4777

普通的單點修改單點查詢就不講了,從區間修改和單點查詢講起。

原來的值存在a裡面,多建立個陣列c1,注意:c1[i]=a[i]-a[i-1]。

那麼求a[i]的值的時候a[i]=a[i-1]+c1[i]=a[i-2]+c1[i]+c1[i-1]=…..=c1[1]+c1[2]+…+c1[i]。

所以就用c1建立樹狀陣列,便可以很快查詢a[i]的值。不多說,見**。

#include#include#define lb(x) x&-x

#define maxn 1000000

#define in(x) scanf("%d",&x)

#define in3(x,y,z) scanf("%d%d%d",&x,&y,&z)

using namespace std;

int a[maxn],c1[maxn],n,m,val,x,y,temp;

void update(int x,int val)

}int sum(int x)

return ans;

}main()

while(m--)

else

}}

自認為還是比較好看懂的,接下來是區間修改和區間查詢了。

我們用sum(1,k)表示區間1到k的和。

那麼sum(1,k)=c1(1)+(c1(2)+c1(2))+(c1(1)+c1(2)+c1(3))+…+(c1(1)+c1(2)+…+c1(k))。

然後我們把式子開啟。

sum(1,k)=k*(c1(1)+c1(2)+c1(3)+…+c1(k))-(0*c1*(1)+1*c1(2)+2*c1(3)+…+(k-1)*c1(k))。

是不是有些小激動,我們可以多建立乙個陣列c2,c2[n]用來存(n-1)*c1(n),並且把c2陣列也建立成樹狀陣列,那麼問題就迎刃而解了。

詳見**:

#include#include#define lb(x) x&-x

#define ll long long

#define maxn 1000000

#define in(x) scanf("%lld",&x)

#define in3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)

using namespace std;

ll a[maxn],c1[maxn],c2[maxn],n,m,val,x,y,temp;

void update(ll *q,ll x,ll val)

}ll getsum(ll *q,ll x)

return ans;

}ll sum(ll x)

ll inquire(ll x,ll y)

int main()

for(ll i=1; i<=m; i++)

else

}}

樹狀陣列 區間修改 單點查詢

說一下差分 現在我們有乙個從小到大的數列a a 1 3 6 8 9 然後還有乙個差分陣列b b 1 2 3 2 1 對應 1,3 1,6 3,8 6,9 8,相信某些同學絕已經看出端倪了.這裡b i a i a i 1 我令a 0 0,故b 1 a 1 int now 0,temp scanf d ...

樹狀陣列(區間修改,單點查詢)

如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的值 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表示乙個操作,具體如下 操...

樹狀陣列 單點修改區間查詢

樹狀陣列,時間複雜度o mlogn 明顯優於暴力列舉以及字首和,主要用於單點修改區間查詢 當然還有區間修改單點查詢 如果一道題中只有區間查詢,那麼建議使用字首和維護 思想直接理解不好理解,借助資料 a陣列下標12 3456 78數值2 5632 714以上是我們要儲存的a陣列,就是原資料 b陣列下標...