HYSBZ
来源:互联网 发布:dell笔记本 centos 编辑:程序博客网 时间:2024/06/03 08:54
树链剖分就是将一个树的路径转化成重链和轻链,对其节点或者边就行编号,从而可以转化成其他的数据结构问题来解决问题。树链剖分有些类似莫队,也就是相当于把树的路径进行了分块。
数组的含义:
fa[]每个节点的父节点
num[]每个节点子节点的个数(包含自己)
son[v]与v在同一重链的重儿子
top[v]节点v所在链的顶端节点(v可以是一个单独的点,相当于自己组成一条重链)
pos[v]节点v编号后在线段树中的编号
pre[v]v节点之前的编号
deep[v]节点v在树中的深度(根深度为1)
修改或者查询时:
对于[u,v]区间,f1=top[u],f2=top[v],ql,qr分别为左右端点
有两种情况(deep[f1]>deep[f2]):
f1!=f2: ql=pos[top[u]],qr=pos[u],再更新u=fa[top[u]]
f1==f2: ql=pos[u],qr=pos[v] (deep[u] < deep[v])
重复循环上面的过程,ql,qr就是需要查询和修改的左右区间
【HYSBZ - 1036 树的统计】
这个题是裸的树剖加线段树
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
41 22 34 14 2 1 312QMAX 3 4QMAX 3 3QMAX 3 2QMAX 2 3QSUM 3 4QSUM 2 1CHANGE 1 5QMAX 3 4CHANGE 3 6QMAX 3 4QMAX 2 4QSUM 3 4
Sample Output
412210656516
#include<cstdio>#include<algorithm>#include<vector>#include<cstring>using namespace std;const int maxn = 1e5 + 5;struct node { int l, r, maxx, sum;}tree[maxn<<2];int pos[maxn], pre[maxn], value[maxn], son[maxn], num[maxn], top[maxn], deep[maxn],fa[maxn];int n, tot, q;vector<int>e[maxn];void dfs1(int u,int f,int dep){ deep[u] = dep; num[u] = 1; fa[u] = f; for (int i = 0; i < e[u].size(); i++) { int v = e[u][i]; if (v == fa[u]) continue; dfs1(v, u, dep + 1); num[u] += num[v]; if (num[v] > num[son[u]]) son[u] = v; }}void dfs2(int u,int tp){ pos[u] = ++tot; pre[pos[u]] = u; top[u] = tp; if (son[u]) dfs2(son[u], tp); for (int i = 0; i < e[u].size(); i++) { int v = e[u][i]; if (v == fa[u] || v == son[u]) continue; dfs2(v, v); }}inline void pushup(int rt){ tree[rt].maxx = max(tree[rt << 1].maxx, tree[rt << 1 | 1].maxx); tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;}void build(int l, int r, int rt){ tree[rt].l = l; tree[rt].r = r; if (l == r) { tree[rt].maxx = tree[rt].sum = value[pre[l]]; return; } int mid = l + r >> 1; build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1); pushup(rt);}void update(int pos, int rt, int val){ if (tree[rt].l == tree[rt].r) { tree[rt].sum = tree[rt].maxx = val; return; } int mid = tree[rt].l + tree[rt].r >> 1; if (pos <= mid) update(pos, rt << 1, val); else if (pos > mid) update(pos, rt << 1 | 1, val); pushup(rt);}pair<int, int> query(int l, int r, int rt){ pair<int, int>ret; if (l == tree[rt].l&&r == tree[rt].r) { ret.first = tree[rt].maxx; ret.second = tree[rt].sum; return ret; } int mid = tree[rt].l + tree[rt].r >> 1; if (r <= mid) return query(l, r, rt << 1); else if (l > mid) return query(l, r, rt << 1 | 1); else { pair<int, int>a, b; a = query(l, mid, rt << 1); b = query(mid + 1, r, rt << 1 | 1); ret.first = max(a.first, b.first); ret.second = a.second + b.second; return ret; } pushup(rt);}int getsum(int u, int v){ int f1 = top[u], f2 = top[v], ret = 0; while (f1 != f2) { if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); } ret += query(pos[top[u]], pos[u], 1).second; u = fa[f1]; f1 = top[u]; } if (deep[u] < deep[v]) swap(u, v); ret += query(pos[v], pos[u], 1).second; return ret;}int getmax(int u, int v){ int f1 = top[u], f2 = top[v], ret = -0x3f3f3f3f; while (f1 != f2) { if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); } ret =max(ret, query(pos[top[u]], pos[u], 1).first); u = fa[f1]; f1 = top[u]; } if (deep[u] < deep[v]) swap(u, v); ret = max(ret, query(pos[v], pos[u], 1).first); return ret;}int main(){ scanf("%d",&n); for (int i = 1; i < n; i++) { int a, b; scanf("%d%d",&a,&b); e[a].push_back(b); e[b].push_back(a); } for (int i = 1; i <= n; i++) scanf("%d",&value[i]); dfs1(1, 1, 1); dfs2(1, 1); build(1, tot, 1); scanf("%d",&q); for (int i=1 ; i <= q; i++) { char op[10]; int u, v; scanf("%s%d%d",op,&u,&v); if (strcmp(op, "QSUM") == 0) { printf("%d\n",getsum(u,v)); } else if (strcmp(op, "QMAX") == 0) { printf("%d\n", getmax(u, v)); } else { update(pos[u], 1, v); } } return 0;}
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- HYSBZ
- 受限玻尔兹曼机(RBM, Restricted Boltzmann machines)和深度信念网络(DBN, Deep Belief Networks)
- Logstash 配置总结
- C+++Primer+4th+中英文
- [转]对于python setup.py install安装的包如何卸载
- spring+springmvc+mybatis+shiro+ehcache集成demo
- HYSBZ
- 剑指offer出现的返回值错误。
- MySQL性能优化的最佳20+条经验
- SwitchHosts免安装版
- lvs+keepalived实现高可用samba集群
- 关于js分页
- Jlink 怎样烧录nrf52832,使蓝牙设备名称流水号自动++
- windows64位系统通过powerdesigner连接mysql反向生成pdm文件
- Js中的数组