線段樹演算法總結

2021-07-05 22:40:37 字數 3312 閱讀 5992

問題一:給你n個數和m次操作,操作分兩種——

1,u a b 第a個數增加b;2,s a b  求區間[a, b]的和。

#include #include #include #define maxn 100000+10

using namespace std;

int sum[maxn<<1];

int n, m;

int lowbit(int x)

void update(int x, int d)

}int query(int x)

return ans;

}int main()

while(m--)

}return 0;

}

問題二:給你n個數和m次操作,操作分三種——

1,u a b 第a個數變成b;2,s a b 求區間[a, b]的和;3,m a b 求區間[a, b]的最大值 

#include #include #include #define maxn 100000+10

using namespace std;

int sum[maxn<<2];

int max[maxn<<2];

void pushup(int o)

void build(int o, int l, int r)

int mid = (l + r) >> 1;

build(o<<1, l, mid);

build(o<<1|1, mid+1, r);

pushup(o);

}void update(int o, int l, int r, int pos, int val)

int mid = (l + r) >> 1;

if(pos <= mid)

update(o<<1, l, mid, pos, val);

else

update(o<<1|1, mid+1, r, pos, val);

pushup(o);

}int querysum(int o, int l, int r, int l, int r)

return ans;

}int querymax(int o, int l, int r, int l, int r)

return ans;

}int main()

}return 0;

}

問題三:給你n個數和m次操作,操作有兩種——

1,a a b c 區間[a, b]所有數修改為c; 2, q a b 求區間[a, b]所有數之和。

#include #define max 100000+10

int col[max<<2];

int sum[max<<2];

void pushup(int o)

void pushdown(int o, int m)

}void build(int o, int l, int r)//建樹

int mid = (l + r) >> 1;

build(o<<1,l, mid);

build(o<<1|1, mid+1, r);

pushup(o);

}void update(int o, int l, int r, int l, int r, int v)//更新

pushdown(o , r - l + 1);

int mid = (l + r) >> 1;

if (l <= mid) update(o<<1, l, mid, l , r , v);

if (r > mid) update(o<<1|1, mid+1, r, l , r , v);

pushup(o);

}int query(int o, int l, int r, int l, int r) //查詢

pushdown(o, r-l+1);

int mid = (r+l) >> 1;

int res = 0;

if(l <= mid)

res += query(o<<1, l, mid, l, r);

if(r > mid)

res += query(o<<1|1, mid+1 , r, l, r);

return res;

}int main()

else if(op == 'q')}}

return 0;

}

問題四:給你n個數和m次操作,操作分兩種——

1,c a b c 把區間[a, b]所有數全加c; 2,q a b 求區間[a, b]所有數之和。

#include#include#define max 100000+10

using namespace std;

int sum[max<<2];

int add[max<<2];

void pushup(int o)

void pushdown(int o, int m)

}void build(int o,int l,int r)//建樹

int mid = (r+l) >> 1;

build(o<<1, l, mid);

build(o<<1|1, mid+1, r);

pushup(o);

}void update(int o, int l, int r, int l, int r, int v)//更新

pushdown(o, r-l+1);

int mid = (r+l) >> 1;

if(l <= mid) update(o<<1, l, mid, l, r, v);

if(r >mid) update(o<<1|1, mid+1, r, l, r, v);

pushup(o);

}int query(int o, int l, int r, int l, int r)//查詢

pushdown(o, r-l+1);

int mid = (r+l) >> 1;

int res = 0;

if(l <= mid)

res += query(o<<1, l, mid, l, r);

if(r >mid)

res += query(o<<1|1, mid+1, r, l, r);

return res;

}int main()

else if(op == 'q')//區間[a,b]所有數之和}}

return 0;

}

線段樹總結

線段樹總結 線段樹的原理就是每乙個區間都可以被分成若干個不相交連續區間 重要 線段樹維護的資料 1.自身結構的資料 比如 左兒子 右兒子的編號 2.懶惰標記 整段區間都變成乙個值 或者將要進行什麼操作 根據每次操作的型別 把操作的區間分成若干個不連續的區間 然後把操作的標記賦值給相應的區間 3.答案...

線段樹總結

線段樹的入門級 總結 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中的每乙個非葉子節點 a,b 它的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 因此線段樹是平衡二叉樹,最後的子節點數目為n,即整...

線段樹總結

解決的題目 對區間所對應的一些資料進行修改,查詢。基本步驟 先建樹,然後插入資料,然後更新,查詢。關鍵部分 用線段樹解題,關鍵是要想清楚每個節點要存哪些資訊以及這些資訊如何高效更新,維護,查詢。不要一更新就更新到葉子節點,那樣更新效率最壞就可能變成o n 的了。建樹的方式 1 陣列 若根節點下標為0...