线段树
来源:互联网 发布:javascript 数组去重 编辑:程序博客网 时间:2024/06/08 03:07
线段树是一个用一个数组,想象一棵完全二叉树,赋予其一些意义,数组中存储的信息即为每个节点
数组中的0 是不用的。
#define MAX 10000 //待处理的点数,不是树中的节点数int tree[MAX * 4];void build(int t, int l, int r){ if (l == r) { //cin>>tree[t]; //tree[t]=0; //对叶子初始化 return; } int mid = l + r >> 1; build(t << 1, l, mid); build(t << 1 | 1, mid + 1, r); //tree[t] = tree[t << 1] + tree[t << 1 | 1]; //tree[t] = max(tree[t << 1], tree[t << 1 | 1]); //对儿子节点递归完可以再用当前点的儿子更新当前点}//----------------------------------------------------------------------void point_update(int t, int l, int r,int x,int y)//将a[x]改为y,点更新{ if (l == r) { //tree[t] = y; return; } int mid = l + r >> 1; if (x <= mid) //x在左边 point_update(t << 1, l, mid, x, y);//继续将xy传参 else if (x > mid) //x在右边 point_update(t << 1 | 1, mid + 1, r, x, y); //tree[t] = tree[t << 1] + tree[t << 1 | 1]; //tree[t] = max(tree[t << 1], tree[t << 1 | 1]); //对儿子节点递归完可以再用当前点的儿子更新当前点}//-----------------------------------------------------------------------------------------int ans;void query(int t, int l, int r, int x, int y)//询问[x,y]的某东西,如最大值。区间查询,需要一个全局变量{ if (x <= l&&y >= r) //当前区间属于[x,y] { //ans += tree[t]; return; } int mid = l + r >> 1; if (y <= mid) //y<=mid说明整个查询区间都在左边 query(t << 1, l, mid, x, y);//继续将xy传参 else if (x > mid) //x>mid说明整个查询区间都在右边 query(t << 1 | 1, mid + 1, r, x, y); else //区间跨过mid ,则分别往左右儿子递归 { query(t << 1, l, mid, x, y); query(t << 1 | 1, mid + 1, r, x, y); }}//-------------------------------------------------------------------------//区间更新还需要记录下每个节点打的标记struct node{ int num; int flag;}tre[MAX*4];void interval_update(int t, int l, int r, int x, int y,int z)//[x,y]内的数都加z{ if (x <= l&&y >= r) //当前区间属于[x,y],不用再往下走,直接在这里打标记 { tre[t].flag += z; return; } int mid = l + r >> 1; if (y <= mid) //y<=mid说明整个查询区间都在左边 interval_update(t << 1, l, mid, x, y,z);//继续将xy传参 else if (x > mid) //x>mid说明整个查询区间都在右边 interval_update(t << 1 | 1, mid + 1, r, x, y,z); else //区间跨过mid ,则分别往左右儿子递归 { interval_update(t << 1, l, mid, x, y,z); interval_update(t << 1 | 1, mid + 1, r, x, y,z); }}void travel(int t, int l, int r, int f)//f为当前点所以祖先的flag之和{ if (l == r) { tre[t].num += f; tre[t].num += tre[t].flag;//应加上所有祖先的flag和自己的 return; } int mid = l + r >> 1; travel(t << 1, l, mid,f+tre[t].flag); travel(t << 1 | 1, mid + 1, r,f+tre[t].flag); //tree[t] = tre[t << 1].num + tre[t << 1 | 1].num; //tree[t] = max(tre[t << 1].num, tre[t << 1 | 1].num); //对儿子节点递归完可以再用当前点的儿子更新当前点}
阅读全文
1 0
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 超超超简单的bfs——POJ-1915
- 2017-6-4 CTF解题报告
- HDU 6103
- DAY 0
- PC通过WIFI连接Android设备,使用ADB
- 线段树
- JS 随手记
- symbol lookup error
- 单源最短路径(spfa)
- 计算几何
- 51NOD-1086 背包问题 V2
- POJ 1258 Agri-Net
- Caused by: tag 'select', field 'list', name 'Model.属性': The requested list key '@*.*.*.*.*.EmpModel@
- 度度熊与邪恶大魔王 DP | 完全背包