E. Jamie and Tree(树链剖分 + 线段树)

E. Jamie and Tree

思路

  • 直接root=vroot = vroot=v

  • lcalcalcalca=lca(root,u),lca(root,v),lca(u,v)lca = {lca(root, u), lca(root, v), lca(u, v)}lca=lca(root,u),lca(root,v),lca(u,v)depdepdep最深的:

    • rootrootroot不在lcalcalca的子树上:

      直接[l[lca],r[lca]][l[lca], r[lca]][l[lca],r[lca]]区间更新xxx

    • rootrootrootlcalcalca的子树上:

      先把整棵树更新一遍+x,然后找到root−>lcaroot -> lcaroot>lca路径上与lcalcalca的儿子节点,然后更新他的子树-x

  • 操作三:

    • rootrootroot不在vvv的子树上:

      直接sum(l[v],r[v])sum({l[v], r[v]})sum(l[v],r[v])

    • rootrootrootvvv的子树上:

      +sum(1,n)+ sum(1, n)+sum(1,n)

      −sum(nextsonoflca)-sum(next_{son\ of\ lca})sum(nextson of lca)类似操作二。

最后,操作二要特判一下root==lcaroot == lcaroot==lca和操作三要特判一下root=vroot = vroot=v,这个时候直接修改或者查询整个[1,n][1, n][1,n]的区间。

代码

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1, root;int son[N], sz[N], dep[N], fa[N], top[N], rk[N], id[N], l[N], r[N], tot;ll sum[N << 2], lazy[N << 2], value[N], n, m;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs1(int rt, int f) {dep[rt] = dep[f] + 1;sz[rt] = 1, fa[rt] = f;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == f) continue;dfs1(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}
}void dfs2(int rt, int tp) {rk[++tot] = rt, id[rt] = tot;top[rt] = tp;l[rt] = r[rt] = tot;if(!son[rt]) return ;dfs2(son[rt], tp);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa[rt] || to[i] == son[rt]) continue;dfs2(to[i], to[i]);}r[rt] = tot;
}void push_down(int rt, int l, int r) {if(lazy[rt]) {lazy[ls] += lazy[rt], lazy[rs] += lazy[rt];sum[ls] += 1ll * (mid - l + 1) * lazy[rt];sum[rs] += 1ll * (r - mid) * lazy[rt];lazy[rt] = 0;}
}void push_up(int rt) {sum[rt] = sum[ls] + sum[rs];
}void build(int rt, int l, int r) {if(l == r) {sum[rt] = value[rk[l]];return ;}build(lson);build(rson);push_up(rt);
}void update(int rt, int l, int r, int L, int R, int w) {if(l >= L && r <= R) {lazy[rt] += w;sum[rt] += 1ll * (r - l + 1) * w;return ;}push_down(rt, l, r);if(L <= mid) update(lson, L, R, w);if(R > mid)  update(rson, L, R, w);push_up(rt);
}ll query(int rt, int l, int r, int L, int R) {if(l >= L && r <= R) return sum[rt];push_down(rt, l, r);ll ans = 0;if(L <= mid) ans += query(lson, L, R);if(R > mid)  ans += query(rson, L, R);return ans;
}int Lca(int x, int y) {while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x, y);x = fa[top[x]];}return dep[x] < dep[y] ? x : y;
}int Max(int x, int y) {return dep[x] > dep[y] ? x : y;
}void update(int x, int y, int value) {while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x, y);update(1, 1, n, id[x], id[top[x]], value);x = fa[top[x]];}if(dep[x] > dep[y]) swap(x, y);update(1, 1, n, id[x], id[y], value);
}ll query(int x, int y) {ll ans = 0;while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x, y);ans += query(1, 1, n, id[x], id[top[x]]);x = fa[top[x]];}if(dep[x] > dep[y]) swap(x, y);ans += query(1, 1, n, id[x], id[y]);return ans;
}int get(int u) {int v = root;while(top[v] != top[u]) {if(fa[top[v]] == u) return top[v];v = fa[top[v]];}return son[u];
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read(), m = read();for(int i = 1; i <= n; i++) {value[i] = read();}for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs1(1, 0);dfs2(1, 1);build(1, 1, n);root = 1;for(int i = 1; i <= m; i++) {int op = read();if(op == 1) {root = read();}else if(op == 2) {int u = read(), v = read(), x = read();int lca = Max(Max(Lca(u, v), Lca(root, v)), Lca(root, u));if(lca == root) {update(1, 1, n, 1, n, x);}else {if(id[root] < l[lca] || id[root] > r[lca]) {update(1, 1, n, l[lca], r[lca], x);}else {lca = get(lca);update(1, 1, n, 1, n, x);update(1, 1, n, l[lca], r[lca], -x);}}}else {int v = read();if(v == root) {printf("%lld\n", query(1, 1, n, 1, n));}else {if(id[root] < l[v] || id[root] > r[v]) {printf("%lld\n", query(1, 1, n, l[v], r[v]));}else {ll ans = query(1, 1, n, 1, n);v = get(v);ans -= query(1, 1, n, l[v], r[v]);printf("%lld\n", ans);}}}}return 0; 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[2021.1.17多校省选模拟4]T1(莫比乌斯反演/组合数学/枚举倍数)

[2021.1.17多校省选模拟4]T1 一般人都会想着去枚举直线的斜率&#xff0c;但是枚举斜率之后就会产生多条直线&#xff0c;并且这些直线的长度不一&#xff0c;难以快速求解&#xff0c;所以我们考虑换一种方法枚举。 枚举最远点对的横纵坐标之差&#xff0c;这样很容易计算这…

程序员35岁不转型就退休,是真的吗?

周六下午&#xff0c;DevOps群里&#xff0c;有人贴出来这么一张图&#xff1a;据说&#xff0c;这张图来自于谷歌&#xff0c;Google程序员之间存在这一条鄙视链&#xff0c;站在顶端的是C工程师&#xff0c;其次是Java工程师&#xff0c;再次是Python工程师&#xff0c;接下来…

Java修炼之路——基础篇——平台无关性

Java如何实现平台无关性&#xff1f; 首先说无论是哪种语言&#xff0c;都需要经过操作系统和CPU来完成程序的运行。平台无关性指的是程序不会因为操作系统和处理器的不同而不能运行或者发生运行错误。而不同的CPU和OS组成的平台的机器指令是不同的。 C\C等语言&#xff0c;需…

.net测试篇之Moq框架简单使用

Moq简介Moq是.net平台下的一个非常流行的模拟库,只要有一个接口它就可以动态生成一个对象,底层使用的是Castle的动态代理功能.它的流行赖于依赖注入模式的兴起,现在越来越多的分层架构使用依赖注入的方式来解耦层与层之间的关系.最为常见的是数据层和业务逻辑层之间的依赖注入,…

LibreOJ #6207. 米缇(杜教筛 + 拉格朗日插值)

#6207. 米缇 推式子 ∑i1n∑j1ndK(ij)∑i1n∑j1n∑x∣i∑y∣j[gcd(x,y)1]ixkyk∑i1n∑j1n∑x∣i∑y∣j∑d∣gcd(x,y)μ(d)ixkyk∑d1nμ(d)dk∑i1nd∑x∣iixk∑j1nd∑y∣iyk∑d1nμ(d)dk∑i1nd∑x∣ixk∑j1nd∑y∣iyk∑d1nμ(d)dk(∑i1nd∑x∣ixk)2∑d1nμ(d)dk(∑x1ndxk∑x∣i…

Java修炼之路——基础篇——值传递

什么是值传递&#xff1f;引用传递&#xff1f; 值传递&#xff1a;值传递是将变量的一个副本传递到方法中&#xff0c;方法中如何操作该副本&#xff0c;都不会影响原变量的值。引用传递&#xff1a;引用传递是将变量的地址传递到方法中&#xff0c;方法中操作该变量&#xf…

A. 树与路径(树论/多项式/分治FFT)

A. 树与路径 首先考虑一个dp的方法&#xff0c;对于这种链划分的题目&#xff0c;有一个很重要的思想就是按照每个点的角度考虑&#xff0c;实际上链划分就是匹配问题&#xff0c;每个点只能出一条边和入一条边&#xff0c;所以我们拆点之后就是匹配&#xff0c;这也是网络流最…

.NET Core on K8S学习实践系列文章索引(持续更新)

近期在学习Kubernetes&#xff0c;基于之前做笔记的习惯&#xff0c;已经写了一部分文章&#xff0c;因此给自己立一个2019年的flag&#xff1a;完成这个《.NET Core on K8S学习实践》系列文章&#xff01;这个系列会持续更新&#xff0c;先发个草稿列表&#xff0c;后续更新&a…

Java修炼之路——基础篇——数据类型

基础数据类型&#xff1a; 整型&#xff08;byte short int long &#xff09;、浮点型、布尔型、字符型boolean:只表示一位的信息&#xff0c;true,false。默认为false&#xff0c;基本上占一字节char: 16位&#xff0c;2字节&#xff0c;Java内部使用Unicode字符集最小值是’…

dft + fft(模板)

dft(多项式相乘模板) /*Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc.h>using namespace std;const double pi acos(-1.0);const int N 3e6 10;struct Complex {double r, i;Complex(double _r 0, double _i 0) : …

P4245 【模板】任意模数多项式乘法

P4245 【模板】任意模数多项式乘法 https://www.luogu.com.cn/blog/AzusaCat/solution-p4245 首先这类问题指的是对于一个非NTT模数&#xff0c;我们如何计算多项式乘法&#xff0c;对于NTT不容易找到单位根&#xff0c;对于FFT又会爆精度。 方法1&#xff1a;三模数NTT 寻找…

2019-02-22-算法-进化

题目描述&#xff1a; 给定一个字符串&#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: "bbbbb" 输出: 1 …

TomatoLog-1.1.0实现ILoggerFactory

TomatoLogTomatoLog 是一个基于 .NETCore 平台的产品。The TomatoLog 是一个中间件&#xff0c;包含客户端、服务端&#xff0c;非常容易使用和部署。客户端实现了ILoggerFactory&#xff0c;使用服务注入成功后即可使用&#xff0c;对业务入侵非常小&#xff0c;也支持通过客户…

HDU 4609 3-idiots(FFT)

3-idiots 思路 多项式卷积的经典应用了&#xff1a; 看样例一: 4 1 3 3 4我们用多项式系数表示得到一个与aia_iai​有关的多项式&#xff1a;010210\ 1\ 0\ 2\ 10 1 0 2 1&#xff0c; 也就说明原序列有0个1&#xff0c;1个1&#xff0c;0个2&#xff0c;2个3&#xff0c;…

P5488 差分与前缀和(多项式/生成函数)

P5488 差分与前缀和 对于这道题需要我们快速对一个数列求解前缀和和差分&#xff0c;那么我们利用生成函数的知识&#xff0c;就可以知道实际上等价于乘一个多项式&#xff0c;然后我们就有了一个ln和exp的方法&#xff0c;然后比较简短的方法就是将其利用广义二项式定理展开&…

2019-02-23-算法-进化

题目描述&#xff1a;给定一个字符串 s&#xff0c;找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1&#xff1a; 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。示例 2&#xff1a; 输入: "cbbd" 输…

Docker(二)-在Docker中部署Nginx实现负载均衡(视频)

一、前言在前面的文章中我们已经介绍了如何在Centos7系统中安装Docker以及利用Docker进行Asp.Net Core应用的部署。在本文中&#xff0c;我们将继续介绍利用Docker部署Nginx服务实现负载均衡&#xff0c;我们通过视频方式向大家进行演示。注&#xff1a;查看公众号历史文章&…

P4389 付公主的背包(生成函数/多项式)

P4389 付公主的背包 https://www.luogu.com.cn/problem/solution/P4389 经典生成函数问题 求解无限背包问题&#xff0c;我们可以将每个物品看作一个多项式&#xff0c;那么最后的结果就是这些多项式的卷积的系数&#xff0c;然后我们实际上就可以考虑分治NTT了&#xff0c;但…

HDU 6265 Master of Phi

Master of Phi 推式子 ∑d∣nϕ(nd)d给出了n的唯一分解形式我们先对上面式子进行化简通过组合枚举d&#xff0c;d的取值分别可以通过∏i1m∑j0qipij&#xff0c;一个多项式组合得到那么上述的式子有没有可能也通过这种新式得到呢&#xff0c;好像是可以的∑d∣nϕ(nd)d∏i1m∑…

Docker系列之镜像瘦身(五)

本节我们来讲讲在我们在构建镜像过程中不出问题&#xff0c;同时使得最后所构建的镜像文件大小尽可能最小。缓存(cache)Docker的优势之一在于提供了缓存&#xff0c;加速镜像迭代构建&#xff0c;我们知道构建镜像使用docker build命令&#xff0c;也就是说通过docker build的缓…