哪种网站开发简单广州品牌策划公司排行
#PermanentNotes/algorithm
思想
首先关于树有许多类型,这里我们主要首线段树,整体思想就是将一个大区间进行拆分,拆分成各个小区间,在我们进行查找,更新时,就是对区间的查找更新
类型
初始化,构建树
代码
const int Z = 1e7;
const ll INF = 1e18;
const int maxn= 1e5 + 10;
const int maxnn = maxn << 2;
int N, M, E;ll tree[maxnn];void build(int l, int r, int k) {if (l == r) {tree[k] = INF;//在这里,我经常将它的节点写成它的l return;}int mid = l + r >> 1;int lc = k << 1;int rc = k << 1 | 1;build(l, mid, lc);build(mid + 1, r, rc);tree[k] = min(tree[lc], tree[rc]);
}
在我们的初始化当中,一定要根据题意,确定我们最开始要初始的值(我们假设我们求的是一个区间最小值,那么将每个区间都初始化为最大值)
单点更新
代码
这里,我们假设求最小值
void pushup(int rt)
{tree[rt] = min(tree[rt << 1], tree[rt << 1 | 1]);
}void update(int pos,ll c,int l,int r,int rt)
{if(l==r){tree[rt]=min(tree[rt],c);return ;}int m=(l+r)>>1;if(pos<=m) update(pos,c,lson);if(pos> m) update(pos,c,rson);pushup(rt);
}
区间查找
我们假设查找一个区间的最小值
代码
ll query(int L, int R, int l, int r, int rt)
{if (L <= l && r <= R) {return tree[rt];}int m = (l + r) >> 1;ll ret = inf;int lc=rt<<1;int rc=rt<<1|1;if (L <= m) ret = min(ret, query(L, R, l,m,lc));if (R > m) ret = min(ret, query(L, R, m+1,r,rc));return ret;
}
区间修改(懒标记法)
每次在进行左右区间(lc,rc)操作之前,先进行pushdown对,对lc,rc操作完毕之后再pushup
typedef long long ll;#define lc p<<1
#define rc p<<1|1const int N = 1e5;
int a[N];
struct node {int l;int r;ll sum;ll add;
}tr[4 * N];void pushup(int p) {tr[p].sum = tr[lc].sum + tr[rc].sum;
}
void pushdown(int p) {if (tr[p].add) {tr[lc].sum += (tr[lc].r - tr[lc].l + 1) * tr[p].add;tr[rc].sum += (tr[rc].r - tr[rc].l + 1) * tr[p].add;tr[lc].add += tr[p].add;tr[rc].add += tr[p].add;tr[p].add = 0;}
}void build(int p, int l, int r) {tr[p] = { l,r,a[l],0 };if (l == r)return;int m = l + r >> 1;build(lc, l, m);build(rc, m + 1, r);pushup(p);
}void update(int p, int x, int y, int k) {if (x <= tr[p].l && tr[p].r <= y) {tr[p].sum += (tr[p].r - tr[p].l + 1) * k;tr[p].add += k;return;}int m = tr[p].l + tr[p].r >> 1;pushdown(p);if (x <= m)update(lc, x, y, k);if (m < y)update(rc, x, y, k);pushup(p);
}ll query(int p, int x, int y) {if (x <= tr[p].l && tr[p].r <= y)return tr[p].sum;int m = tr[p].l + tr[p].r >> 1;pushdown(p);ll sum = 0;if (x <= m)sum += query(lc, x, y);if (m < y)sum += query(rc, x, y);return sum;
}
推荐视频b站up董晓算法我的算法都是在这儿学的
线段树例题
acwing243
洛谷p3372
洛谷p3373