題目
分析
樹狀陣列在區間查詢和單點修改情況下效率較線段樹高一些,而無法像線段樹一樣在o(logn)的時間內完成區間修改。因此使用線段樹解決。使用線段樹主要的是定義好線段樹節點的狀態。(如**中注釋所說,狀態一定要明確,且容易計算!)
實現
#include#include#include#include#include#include#include#include#includeusing namespace std;const int inf = 1 << 29;
const int kmax = 100005;
struct node
};node gnodes[4 * kmax];
int weight[kmax];
void buildtree(int node, int beg, int end)
int left = 2 * node + 1, right = 2 * node + 2;
int mid = (beg + end) / 2;
buildtree(left, beg, mid);
buildtree(right, mid + 1, end);
gnodes[node].sum = gnodes[left].sum + gnodes[right].sum;
}//從上向下更新
void pushdown(int node)
int left = 2 * node + 1, right = 2 * node + 2;
if (gnodes[node].val)
gnodes[node].val = 0;
}//從下向上更新
void pushup(int node)
int left = 2 * node + 1, right = 2 * node + 2;
gnodes[node].sum = gnodes[left].sum + gnodes[right].sum;
}void update(int node, int beg, int end, int value)
if (beg > end)
return;
//查詢區間和線段樹節點代表的區間不同,則進行區間分解。 需要先將父節點的資訊傳遞給子節點
pushdown(node);
int left = 2 * node + 1, right = 2 * node + 2;
int mid = (gnodes[node].beg + gnodes[node].end) / 2;
if (mid >= end)
else if(mid < beg)
else
//線段樹子節點更新完之後,需要更新父節點的 sum 資訊
pushup(node);
}int query(int node, int beg, int end)
if (beg > end)
return 0;
pushdown(node);
int left = 2 * node + 1, right = 2 * node + 2;
int mid = (gnodes[node].beg + gnodes[node].end) / 2;
if (mid >= end)
else if (mid < beg)
else
}int main()
buildtree(0, 0, n - 1);
scanf("%d", &n);
int cmd, beg, end, value;
for (int i = 0; i < n; i++)
else
} return 0;
}
hiho 1078 線段樹區間修改
題目 分析 樹狀陣列在區間查詢和單點修改情況下效率較線段樹高一些,而無法像線段樹一樣在o logn 的時間內完成區間修改。因此使用線段樹解決。使用線段樹主要的是定義好線段樹節點的狀態。如 中注釋所說,狀態一定要明確,且容易計算!實現 include include include include i...
hiho 1078 線段樹的區間修改
題意 長度為n的序列上有兩種操作 0 ql qr 輸出區間 ql,qr 和 1 ql qr v 區間 ql,qr 賦值為v 線段樹懶標基礎題,我用分塊寫了乙個,在本題資料竟然跑的飛快 include include include define rep i,a,b for int i a i b i...
線段樹 區間修改
我們對於線段樹的區間修改你可以用乙個最傻的辦法迴圈進行單點修改 時間複雜度太高十分麻瓜 所以,我們要用乙個聰明的做法延遲標記 lazy 我們在執行修改指令時,同樣可以在 l pl pr r 的情況下立即返回,只不過在回溯之前向節點p增加乙個標記,標識 該節點曾經被修改過,但其子節點尚未被更新 如果在...