【树链剖分】[BZOJ1036][ZJOI2008]树的统计Count
来源:互联网 发布:c seo的伪静态 编辑:程序博客网 时间:2024/04/27 10:59
题目描述
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
输入的第一行为一个整数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之间。
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
样例输入
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
样例输出
4
1
2
2
10
6
5
6
5
16
题目分析
我们可以通过观察题目发现emoji难道这不是一个裸的树链剖分么。。。。。。每次操作复杂度
代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 30000;const int MAXQ = 200000;struct node{ int v; node *next;}Edges[MAXN*2+10], *ecnt=Edges, *adj[MAXN+10];int Maxson[MAXN+10], sz[MAXN+10], id[MAXN+10], idcnt, top[MAXN+10], vals[MAXN+10], Dep[MAXN+10], Fa[MAXN+10], revid[MAXN+10];void addedge(int u, int v){ ++ecnt; ecnt->v = v; ecnt->next = adj[u]; adj[u] = ecnt;}void dfs(int u, int fa){ sz[u]=1; Fa[u] = fa; Dep[u]=Dep[fa]+1; for(node *p=adj[u];p;p=p->next){ if(p->v == fa) continue; dfs(p->v, u); sz[u] += sz[p->v]; if(sz[p->v] > sz[Maxson[u]]) Maxson[u] = p->v; }}void dfs2(int u, int tp, int fa){ top[u] = tp; revid[(id[u]=++idcnt)]=u; if(Maxson[u]) dfs2(Maxson[u], tp, u); for(node *p=adj[u];p;p=p->next){ if(p->v==fa||p->v==Maxson[u]) continue; dfs2(p->v, p->v, u); }}struct Tree{ int Max, Sum;}tree[MAXN*4+10];void push_up(int u){ tree[u].Max = max(tree[u*2].Max, tree[u*2+1].Max); tree[u].Sum = tree[u*2].Sum + tree[u*2+1].Sum;}void Update(int u, int l, int r, int p, int v){ if(l == r){ tree[u].Max = tree[u].Sum = v; return ; }else{ int mid = (l + r) >> 1; if(p<=mid)Update(u*2, l, mid, p, v); else Update(u*2+1, mid+1, r, p, v); push_up(u); }}int sumq(int u, int l, int r, int ql, int qr){ if(ql <= l && r <= qr) return tree[u].Sum; else if(ql > r || qr < l) return 0; int mid = (l + r) >> 1; if(ql > mid) return sumq(u*2+1, mid+1, r, ql, qr); else if(qr <= mid) return sumq(u*2, l, mid, ql, qr); return sumq(u*2, l, mid, ql, qr) + sumq(u*2+1, mid+1, r, ql, qr);}int maxq(int u, int l, int r, int ql, int qr){ if(ql <= l && r <= qr) return tree[u].Max; int mid = (l + r) >> 1; if(ql > mid) return maxq(u*2+1, mid+1, r, ql, qr); else if(qr <= mid) return maxq(u*2, l, mid, ql, qr); return max(maxq(u*2, l, mid, ql, qr), maxq(u*2+1, mid+1, r, ql, qr));}int Qsum(int l, int r){ int f1 = top[l], f2 = top[r], ret = 0; while(f1 != f2){ if(Dep[f1] < Dep[f2]){ swap(f1, f2); swap(l, r); } ret += sumq(1, 1, idcnt, id[f1], id[l]); l = Fa[f1]; f1 = top[l]; } if(Dep[l] > Dep[r]) swap(l, r); return ret + sumq(1, 1, idcnt, id[l], id[r]);}int Qmax(int l, int r){ int f1 = top[l], f2 = top[r], ret = -1000000000; while(f1 != f2){ if(Dep[f1] < Dep[f2]){ swap(f1, f2); swap(l, r); } ret = max(ret, maxq(1, 1, idcnt, id[f1], id[l])); l = Fa[f1]; f1 = top[l]; } if(Dep[l] > Dep[r]) swap(l, r); return max(ret, maxq(1, 1, idcnt, id[l], id[r]));}void dfs3(int u, int l, int r){ if(l == r){ tree[u].Max = tree[u].Sum = vals[revid[l]]; return ; } int mid = (l + r) >> 1; dfs3(u*2, l, mid); dfs3(u*2+1, mid+1, r); push_up(u);}int main(){ int n, u, v; scanf("%d", &n); for(int i=1;i<n;i++){ scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); } dfs(1, 0); dfs2(1, 1, 0); for(int i=1;i<=n;i++) scanf("%d", &vals[i]); dfs3(1, 1, idcnt); int q, a, b; char ord[40]; scanf("%d", &q); while(q--){ scanf("%s%d%d", ord, &a, &b); if(ord[0] == 'C') Update(1, 1, idcnt, id[a], b); else{ if(ord[1] == 'S') printf("%d\n", Qsum(a, b)); else printf("%d\n", Qmax(a, b)); } } return 0;}
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
- 【bzoj1036】【树链剖分】【ZJOI2008】树的统计Count
- 【BZOJ1036】【ZJOI2008】【树的统计count】【树链剖分】
- BZOJ1036: [ZJOI2008]树的统计Count (树链剖分)
- bzoj1036: [ZJOI2008]树的统计Count - 树链剖分
- 【树链剖分】[BZOJ1036][ZJOI2008]树的统计Count
- [树链剖分] BZOJ1036: [ZJOI2008]树的统计Count
- [bzoj1036][ZJOI2008]树的统计Count 树链剖分
- 【bzoj1036】【树链剖分】 [ZJOI2008]树的统计Count
- [Bzoj1036][ZJOI2008]树的统计Count
- 【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题
- 【ZJOI2008】【BZOJ1036】树的统计Count
- [BZOJ1036][ZJOI2008]树的统计Count && LCT
- bzoj1036: [ZJOI2008]树的统计Count
- [BZOJ1036][ZJOI2008]树的统计Count
- bzoj1036: [ZJOI2008]树的统计Count
- BZOJ1036: [ZJOI2008]树的统计Count
- C#成神之路<9> C#引用数据类型扩展
- 模板方式
- java中快速创建带初始值的List和Map
- Codeforces 351D:Jeff and Removing Periods
- [POJ 3349]Snowflake Snow Snowflakes[hash]
- 【树链剖分】[BZOJ1036][ZJOI2008]树的统计Count
- 使用cl生成程序
- POJ 1321 棋盘问题(寒假刷题之路)
- cocos2dx-ios接入admob广告
- 一行代码的Python GUI弹框
- Hibernate一对多,多对一双向映射
- 这是一个起点
- Mysql中用function递归查询实例
- 高斯滤波