簡明扼要樹狀陣列

2021-09-25 12:20:28 字數 3066 閱讀 3978

可以發現如下規律:

1=(001)      c[1] = a[1];

2=(010)      c[2] = a[1] + a[2] = c[1] + a[2];

3=(011)      c[3] = a[3];

4=(100)      c[4] = a[1] + a[2] + a[3] + a[4] = c[2] + c[3] + a[4];

5=(101)      c[5] = a[5];

6=(110)      c[6] = a[5] + a[6] = c[5] + a[6];

7=(111)      c[7] = a[7];

8=(1000)    c[8] = a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] = c[4] + c[6] + c[7] + a[8];

c[i] = a[i-2^k+1] + a[i-2^k+2] + ...... + a[i];

其中k表示i的二進位制末尾0的個數

整數在計算機中一般採用補碼儲存,把乙個補碼表示的整數x變成其相反數 -x 相當與把每一位都取反然後末位加一,等價於把x的二進位制最右邊的1左邊的每一位都取反。因此 lowbit(x) 就是取 x 的二進位制最右邊的 1 和它右邊所有的 0。

lowbit操作:

int lowbit(int x)
更新操作:

void update(int x, int num)

}

求和操作:

int getsum(int x)

return res;

}

例:hdu1166敵兵布陣

#include #include #include using namespace std;

const int maxn = 50005;

int tree[maxn];

int t, n;

int lowbit(int x)

void update(int x, int num)

}int getsum(int x)

return res;

}int main()

cout << "case " << ++cnt << ':' << endl;

string s;

int x, y;

while(cin >> s && s[0] != 'e')

else if(s[0] == 'a')

else}}

return 0;

}

例:洛谷p3368

利用差分的思想,新建乙個陣列 tree[i] = a[i] - a[i-1]

例如對於下面這個陣列

如果我們把[2,5]區間內值加上2,則變成了

所以對 [x, y] 區間進行值的變化為 k,在差分陣列中實際發生變化的只有 tree[x] 和 tree[y-1]

在 update 函式中傳參為 update(x, k),update(y-1, -k)

#include using namespace std;

const int maxn = 5e5 + 7;

int tree[maxn];

int a[maxn];

int n, m;

int lowbit(int x)

void update(int i, int x)

}int getsum(int i)

return res;

}int main()

int c, x, y, k;

while(m--)

else

}return 0;

}

a[1] + a[2] + …… + a[n]

= tree[1] + (tree[1] + tree[2]) + (tree[1] + tree[2] + tree[3]) + …… + (tree[1] + tree[2] + …… + tree[n])

= n * (tree[1] + tree[2] + …… + tree[n]) - (0 * tree[1] + 1 * tree[2] + 2 * tree[3] + …… + (n - 1) * tree[n])

所以我們維護兩個樹狀陣列 tree1[i] = d[i],tree2[i] = d[i]*(i-1);

void update(int i, int x)

}

int getsum(int i)

return res;

}

例:poj3468

#include #include using namespace std;

typedef long long ll;

const int maxn = 1e5 + 7;

ll tree1[maxn], tree2[maxn], a[maxn];

int n, m;

int lowbit(int x)

void update(int i, ll x)

}ll getsum(int i)

return res;

}int main()

char c;

int x, y, k;

while(m--)

else

}return 0;

}

效能優化 簡明扼要設計模式

設計模式是對物件導向設計中反覆出現的問題的解決方案。這個術語是在1990年代由erich gamma等人從建築設計領域引入到電腦科學中來的。這個術語的含義還存有爭議。演算法不是設計模式,因為演算法致力於解決問題而非設計問題。設計模式通常描述了一組相互緊密作用的類與物件。設計模式提供一種討論軟體設計的...

B樹與B 樹簡明扼要的區別

看了很多講b樹和b 樹的文章,大多都是圍繞各自的特性講的,第一,樹中每個結點最多含有m個孩子 m 2 第二,我也是從這些文章裡弄懂了各種樹的聯絡與區別,要真寫,我可能還不如人家寫得好。所以就在這裡簡明扼要的用幾張圖記錄一下主要區別吧。為了便於說明,我們先定義一條資料記錄為乙個二元組 key,data...

關於軟核 固核 硬核簡明扼要的比較定義 IP核

ip核模組有行為 結構和物理 不同程度的設計,對應描述功能行為的不同分為三類,即軟核 soft ip core 完成結構描述的固核 firm ip core 和基於物理描述並經過工藝驗證的硬核 hard ip core 1 什麼是軟核?ip軟核通常是用hdl文字形式提交給使用者,它經過rtl級設計優...