小 Q 与树(dsu on tree + segment tree)牛客练习赛 81 D

小 Q 与树

给定一棵带权的树,每条边的距离都为111,要我们求∑u=1n∑v=1nmin(au,av)dis(u,v)\sum\limits_{u = 1} ^{n} \sum\limits_{v = 1} ^{n}min(a_u, a_v)dis(u, v)u=1nv=1nmin(au,av)dis(u,v)
min(au,av)dis(u,v)=min(au,av)(dep[u]+dep[v]−2×dep[lca(u,v)])min(a_u, a_v) dis(u, v) = min(a_u, a_v)\left(dep[u] + dep[v] - 2 \times dep[lca(u, v)]\right)\\ min(au,av)dis(u,v)=min(au,av)(dep[u]+dep[v]2×dep[lca(u,v)])

如果考虑 dsu on tree,则是枚举uuu,分两种情况统计答案:

  • au≤ava_u \leq a_vauav,则∑v∈Sau(dep[u]+dep[v]−2×dep[lca(u,v)])\sum\limits_{v \in S} a_u(dep[u] + dep[v] - 2 \times dep[lca(u, v)])vSau(dep[u]+dep[v]2×dep[lca(u,v)]),则我们只要知道集合SSS中有多少个点,以及∑v∈Sdep[v]\sum\limits_{v \in S} dep[v]vSdep[v]即可,

    设点的个数为totaltotaltotal∑v∈Sdep[v]=Sumdep\sum\limits_{v \in S} dep[v] = Sum_{dep}vSdep[v]=Sumdep,则上式等价于au×tatal×(dep[u]−2×dep[lca(u,v)])+au×Sumdepa_u \times tatal \times (dep[u] - 2 \times dep[lca(u, v)]) + a_u \times Sum_{dep}au×tatal×(dep[u]2×dep[lca(u,v)])+au×Sumdep

  • au>ava_u > a_vau>av,则∑u∈Sav(dep[u]+dep[v]−2×dep[lca(u,v)])\sum\limits_{u \in S} a_v(dep[u] + dep[v] - 2 \times dep[lca(u, v)])uSav(dep[u]+dep[v]2×dep[lca(u,v)]),则我们只要知道Sumav×dep[v]Sum_{a_v \times dep[v]}Sumav×dep[v],以及SumavSum_{a_v}Sumav即可求得答案,

    上式等价于Sumav×dep[v]+Sumav×(dep[u]−2×dep[lca(u,v)])Sum_{a_v \times dep[v]} + Sum_{a_v} \times (dep[u] - 2 \times dep[lca(u, v)])Sumav×dep[v]+Sumav×(dep[u]2×dep[lca(u,v)])

所以可以对点权离散化,然后用线段树来维护上面需要的四个值,即可进行 dsu on tree,整体复杂度nlog⁡nlog⁡nn \log n \log nnlognlogn

由于上面的统计我们都是进行的单向计算,所以还要对上述计算完后的答案乘以222即可。

#include <bits/stdc++.h>
#define ls rt << 1
#define rs rt << 1 | 1
#define mid (l + r >> 1)
#define lson ls, l, mid
#define rson rs, mid + 1, rusing namespace std;const int N = 2e5 + 10, mod = 998244353;int head[N], to[N << 1], nex[N << 1], cnt = 1;int son[N], sz[N], l[N], r[N], rk[N], dep[N], tot;int sum1[N << 2], sum2[N << 2], sum3[N << 2], sum4[N << 2];int a[N], b[N], n, m;inline int add(int x, int y) {return x + y < mod ? x + y : x + y - mod;
}inline int sub(int x, int y) {return x >= y ? x - y : x - y + mod;
}inline int mul(int x, int y) {return 1ll * x * y % mod;
}void Add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {dep[rt] = dep[fa] + 1, sz[rt] = 1, l[rt] = ++tot, rk[tot] = rt;for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa) {continue;}dfs(to[i], rt);sz[rt] += sz[to[i]];if (!son[rt] || sz[to[i]] > sz[son[rt]]) {son[rt] = to[i];}}r[rt] = tot;
}void push_up(int rt) {sum1[rt] = add(sum1[ls], sum1[rs]);sum2[rt] = add(sum2[ls], sum2[rs]);sum3[rt] = add(sum3[ls], sum3[rs]);sum4[rt] = add(sum4[ls], sum4[rs]);
}void update(int rt, int l, int r, int x, int v, int op) {if (l == r) {if (op == 1) {sum1[rt] += 1, sum2[rt] = add(sum2[rt], v), sum3[rt] = add(sum3[rt], mul(b[x], v)), sum4[rt] = add(sum4[rt], b[x]);}else {sum1[rt] -= 1, sum2[rt] = sub(sum2[rt], v), sum3[rt] = sub(sum3[rt], mul(b[x], v)), sum4[rt] = sub(sum4[rt], b[x]);}return ;}if (x <= mid) {update(lson, x, v, op);}else {update(rson, x, v, op);}push_up(rt);
}int ans, ans1, ans2, ans3, ans4, ans5;void query(int rt, int l, int r, int L, int R) {if (l >= L && r <= R) {ans1 = add(ans1, sum1[rt]), ans2 = add(ans2, sum2[rt]), ans3 = add(ans3, sum3[rt]), ans4 = add(ans4, sum4[rt]);return ;}if (L <= mid) {query(lson, L, R);}if (R > mid) {query(rson, L, R);}
}void dfs(int rt, int fa, bool keep) {for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa || to[i] == son[rt]) {continue;}dfs(to[i], rt, 0);}if (son[rt]) {dfs(son[rt], rt, 1);}for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa || to[i] == son[rt]) {continue;}for (int j = l[to[i]]; j <= r[to[i]]; j++) {ans1 = ans2 = ans3 = ans4 = 0;query(1, 1, m, a[rk[j]], m);ans = add(ans, mul(ans2, b[a[rk[j]]]));ans = add(ans, mul(b[a[rk[j]]], mul(ans1, sub(dep[rk[j]], 2 * dep[rt]))));if (a[rk[j]] != 1) {ans1 = ans2 = ans3 = ans4 = 0;query(1, 1, m, 1, a[rk[j]] - 1);ans = add(ans, ans3);ans = add(ans, mul(ans4, sub(dep[rk[j]], 2 * dep[rt])));}}for (int j = l[to[i]]; j <= r[to[i]]; j++) {update(1, 1, m, a[rk[j]], dep[rk[j]], 1);}}ans1 = ans2 = ans3 = ans4 = 0;query(1, 1, m, a[rt], m);ans = add(ans, mul(ans2, b[a[rt]]));ans = add(ans, mul(b[a[rt]], mul(ans1, sub(dep[rt], 2 * dep[rt]))));if (a[rt] != 1) {ans1 = ans2 = ans3 = ans4 = 0;query(1, 1, m, 1, a[rt] - 1);ans = add(ans, ans3);ans = add(ans, mul(ans4, sub(dep[rt], 2 * dep[rt])));}update(1, 1, m, a[rt], dep[rt], 1);if (!keep) {for (int i = l[rt]; i <= r[rt]; i++) {update(1, 1, m, a[rk[i]], dep[rk[i]], -1);}}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);b[i] = a[i];}sort(b + 1, b + 1 + n);m = unique(b + 1, b + 1 + n) - (b + 1);for (int i = 1; i <= n; i++) {a[i] = lower_bound(b + 1, b + 1 + m, a[i]) - b;}for (int i = 1, x, y; i < n; i++) {scanf("%d %d", &x, &y);Add(x, y);Add(y, x);}dfs(1, 0);dfs(1, 0, 1);printf("%d\n", mul(2, ans));return 0;
}

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

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

相关文章

多场景抢红包业务引发.NETCore下使用适配器模式实现业务接口分离

事情的起因我们公司现有一块业务叫做抢红包&#xff0c;最初的想法只是实现了一个初代版本&#xff0c;就是给指定的好友单发红包&#xff0c;随着业务的发展&#xff0c;发红包和抢红包的场景也越来越多&#xff0c;目前主要应用的场景有&#xff1a;单聊发红包、群聊发红包、…

设计模式——创建型模型

目录 单例模式&#xff08;singleton&#xff09;构建模式&#xff08;Builder&#xff09;原型模式&#xff08;Prototype&#xff09;工厂方法模式&#xff08;Factory&#xff09;抽象工厂模式&#xff08;Abstract Factory&#xff09; ** 一、5种创建型模型 ** 1.1 单…

Mr. Panda and Kakin(拓展欧几里得 + O(1)快速乘)

Mr. Panda and Kakin 给定n,cn, cn,c&#xff0c;要我们找到nnn是两个相邻质数的乘积&#xff0c;要我们找到xxx&#xff0c;满足x2303≡c(modn)x ^{2 ^{30} 3} \equiv c \pmod nx2303≡c(modn)&#xff0c;1010≤n≤1018,0<c<n10 ^{10} \leq n \leq 10 ^ {18}, 0 <…

【C】KoobooJson在asp.net core中的使用

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。本文链接&#xff1a;https://blog.csdn.net/j_teng/article/details/100924973“KoobooJson是一款体积小巧没有任何依赖且性能表现强劲的Json工具…

单例模式的创建方式

说明&#xff1a; 以下均为线程安全的实现方式。 懒汉、饿汉的非线程安全的意义不大&#xff0c;未实现。 1. 饿汉模式 类初始化时直接创建对象 public class Singleton {private static Singleton singleton new Singleton();//饿汉模式&#xff0c;类初始化时直接创建pub…

P3899 [湖南集训]谈笑风生(线段树合并)

P3899 [湖南集训]谈笑风生 给定一颗以111号节点为根的树&#xff0c;如果a≠ba \neq ba​b&#xff0c;且aaa是bbb的祖先&#xff0c;则aaa比bbb更厉害&#xff0c;如果a≠ba \neq ba​b&#xff0c;且dis(a,b)≤xdis(a, b) \leq xdis(a,b)≤x&#xff0c;xxx为给定的一个…

【DevOps进行时】C/S端界面自动化测试:微软UIAutomation实践

在界面自动化测试领域里存在许多流行的自动化测试工具&#xff0c;例如目前比较受欢迎的开源自动化工具Selenium、Katalon&#xff1b;HP旗下知名的商业软件Unified Functional Testing(更名前叫QTP)&#xff1b;隶属于IBM以数据驱动测试的RTF&#xff08;Rational Functional …

代码编辑器横评:为什么 VS Code 能拔得头筹

2015 年 4 月 29 日的 Build 大会上&#xff0c;微软发布了 Visual Studio Code 第一个预览版本。短短四年时间里&#xff0c;VS Code 高速成长。根据 2019 年 2 月的 PYPL Top IDE index 的排名&#xff0c;VS Code 的涨势迅猛&#xff0c;在所有编辑器与 IDE 中排名第六&…

A. Slackline Adventure(思维 + 莫比乌斯)(2018-2019 ACM-ICPC Brazil Subregional Programming Contest)

A. Slackline Adventure 考虑枚举每个矩形的长跟宽&#xff0c;再统计这个矩形能在坐标轴上出现几次&#xff08;同行相邻同列相邻的单独算&#xff09;&#xff0c;然后有如下式子&#xff1a; 2∑i1n−1∑j1m−1(n−i)(m−j)[gcd⁡(i,j)1][L2≤i2j2≤R2]2 \times \sum_{i 1…

设计模式——结构型模型

一&#xff1a;目录 1. 装饰者模式&#xff08;Decorator&#xff09; 2. 代理模式&#xff08;Proxy&#xff09; 3. 组合模式&#xff08;Composite&#xff09; 4. 桥接模式&#xff08;Bridge&#xff09; 5. 适配器模式&#xff08;Adapter&#xff09; 6. 蝇量模式&#…

D. Best Edge Weight(最小生成树 + 树链剖分)(Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals))

D. Best Edge Weight 给定一个有nnn个点mmm条边的无向连通图&#xff0c;有mmm次询问&#xff0c;每次询问第iii条边的权值最大为多少&#xff0c;这张图的所有最小生成树的方案中&#xff0c;一定包含第iii条边。 先跑一边最小生成树&#xff0c;得到最小生成树&#xff0c;…

利用Helm简化Kubernetes应用部署(1)

目录利用Helm简化Kubernetes应用部署 Helm基础 安装Helm 使用Visual Studio 2019为Helm编写一个简单的应用 利用Helm简化Kubernetes应用部署Helm是Kubernetes生态系统中的一个软件包管理工具&#xff0c;有点类似于Linux操作系统里面的“apt-get”和“yum”。结合上一节内容&am…

设计模式——行为型模式

一&#xff1a;目录 1. 策略模式&#xff08;Strategy&#xff09; 2.状态模式&#xff08;State&#xff09; 3.责任链模式&#xff08;Chain Of Responsibility&#xff09; 4.解释器模式&#xff08;Interpreter&#xff09; 5.命令模式&#xff08;Command&#xff09; 6.观…

2019 ICPC Asia Yinchuan Regional(9 / 13)

2019 ICPC Asia Yinchuan Regional A - Girls Band Party&#xff08;分组背包&#xff09; 每个物品有两个标签&#xff0c;名字&#xff0c;颜色&#xff0c;当名字是设置为奖赏时会对整体加上0.1 的贡献&#xff0c;如果颜色符合要求时 会对整体加上 0.2 的的贡献 但是有…

网络编程——常用协议解析

** 1、网络基础知识 ** 1.1> 什么是OSI模型 OSI 模型(Open System Interconnection model)是一个由国际标准化组织?提出的概念模型,试图?供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的…

在 ABP vNext 中编写仓储单元测试的问题一则

一、问题新项目是基于 ABP vNext 框架进行开发的&#xff0c;所以我要求为每层编写单元测试。在同事为某个仓储编写单元测试的时候&#xff0c;发现了一个奇怪的问题。他的对某个聚合根的 A 字段进行了更新&#xff0c;随后对某个导航属性 B 也进行了变更&#xff0c;最后通过仓…

TCP协议——三次握手与四次关闭

1. TCP协议基础 网络编程基础见&#xff0c;传送门 TCP是面向连接的&#xff0c;无论哪一方向另一方发送数据之前&#xff0c;都必须先在双方之间建立一条连接。 在TCP/IP协议中&#xff0c;TCP协议提供可靠的连接服务&#xff0c;连接是通过三次握手进行初始化的。 三次握手…

在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想

源码&#xff1a;https://github.com/Martin1994/JsonJitSerializerNuGet&#xff1a;https://www.nuget.org/packages/MartinCl2.Text.Json.Serialization/简介&#xff1a;Just-in-time 编译的 JSON 序列化&#xff0c;基于 System.Text.Json.NET Core 3.0 即将正式发布&…

E. Company(Codeforces Round #520 (Div. 2))

E. Company 给定一颗有nnn个节点的树&#xff0c;有mmm次询问&#xff0c;每次询问给定[l,r][l, r][l,r]&#xff0c;我们可以选择删除其中的一个点ppp&#xff0c;然后找到一个深度最深的rtrtrt&#xff0c;使得剩下的点都在rtrtrt的子树上。 考虑对编号为[l,r][l, r][l,r]中…

TCP协议——流量控制和拥塞控制

** 一、流量控制 ** 1.1 什么是流量控制 Sender won’t overflow receiver’s buffer by transmitting too much, too fast. &#xff08;防止发送方发的太快&#xff0c;耗尽接收方的资源&#xff0c;从而使接收方来不及处理&#xff09; 1.2 流量控制的一些知识点 &#x…