SDNUOJ 1665 1668(樹狀陣列的應用)

2021-10-14 07:44:03 字數 2645 閱讀 4862

什麼是樹形陣列:

樹形陣列是一種用來維護字首和的工具,上圖中序列上的就是樹形陣列,它雖然長得像個樹,但是確是乙個陣列,比如上面的t[4]的值就是1-4的字首和,其他元素以此類推。

add操作實現原理:

ask操作實現原理:

下面是區間查詢+單點修改(1665and1666)的**:

#include#includeusing namespace std;

typedef long long ll;

inline int read()

while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();

return s * w;

}inline void write(ll x)

ll lowbit(ll a)

ll dat[100005],tree[100005];//dat是資料陣列,tree是樹形陣列

ll n,q,op,p_l,w_r;

ll ask(ll r)

return ans;

}//ask操作,求1-r的字首和

void add(ll p,ll w)

}//add操作,表現在dat陣列上是讓dat[p]+=w,表現在樹形陣列上是讓含有dat[p]的項都加w

int main()

for(int i=1;i<=n;++i) }

for(int i=1;i<=q;++i)

case 2:

} }return 0;}/*

5 30 0 0 0 0

2 1 100

2 2 1000

1 2 5

*/

下面是另一種構建樹狀陣列的方法(這種比較好,上面那種是我自己按照意思寫的):

#include#includeusing namespace std;

typedef long long ll;

inline int read()

while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();

return s * w;

}inline void write(ll x)

ll lowbit(ll a)

ll dat[100005],tree[100005];//dat是資料陣列,tree是樹形陣列

ll n,q,op,p_l,w_r;

ll ask(ll r)

return ans;

}//ask操作,求1-r的字首和

void add(ll p,ll w)

}//add操作,表現在dat陣列上是讓dat[p]+=w,表現在樹狀陣列上是讓含有dat[p]的項都加w

int main()

for(int i=1;i<=q;++i)

case 2:

} }return 0;}/*

5 30 0 0 0 0

2 1 100

2 2 1000

1 2 5

*/

下面是區間修改+區間查詢(1667and1668)的**:

聽說這種題用線段樹比較好解= =,我用樹狀陣列也就是套了個公式(蒟蒻瑟瑟發抖)。

其中tree1維護了差分陣列b[i]的字首和,tree2維護了i*b[i]的字首和,sum是資料陣列a的字首和。**中沒有寫出差分陣列b是因為可以利用樹狀陣列不用寫出而直接求其字首和。

#include#includeusing namespace std;

typedef long long ll;

ll a[1000005],sum[1000005],tree1[1000005],tree2[1000005];

ll n,q,op,l,r,w;

inline int read()

while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();

return s * w;

}inline void write(ll x)

ll lowbit(ll a)

ll ask1(ll r)

return ans;

}ll ask2(ll r)

return ans;

}void add1(ll p,ll w)

}void add2(ll p,ll w)

}int main()

for(int i=1;i<=q;++i)

case 2:

} }return 0;

}

樹狀陣列2 更高深的樹狀陣列

一 區間修改區間求和 這個東西可就不是把 單點查詢區間修改 和 單點修改區間查詢 合起來那麼簡單了,仔細想想,拿之前的辦法都不咋地好做,那麼怎麼辦呢,我們還是要用到差分陣列,設原陣列為a,差分陣列為b,則b 1 a 1 b i a i a i 1 那麼區間修改我們就解決了,只需要log的時間即可,但...

樹狀陣列的應用

樹狀陣列的應用1 求逆序數 首先考慮將輸入陣列離散化,因為題目要求輸入的數值可以達到10的9次方,肯定不會開出那麼大的陣列。1.定義乙個結構體 val儲存原值,pos儲存原來在陣列中的位置 2.在對原結構體陣列對val值排序 3.定義儲存離散化資料的陣列flect,flect node i pos ...

樹狀陣列的分析

參考 c i 代表 子樹的葉子結點的權值之和 這裡以求和舉例 如圖可以知道 c 1 a 1 c 2 a 1 a 2 c 3 a 3 c 4 a 1 a 2 a 3 a 4 c 5 a 5 c 6 a 5 a 6 c 7 a 7 c 8 a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 ...