【LCT】城市旅行(luogu 4842/金牌导航 LCT-3)

正题

luogu 4842
金牌导航 LCT-3


题目大意

给你一棵树,让你进行一些操作:
1.删除一条边
2.连接一条边
3.给一条路径上的点加上x
4.给出一条路径,在该路径选取两个点,求这两个点之间路径的权值和的期望值


解题思路

该树可以用LCT维护

因为答案用分数表示,且计算过程中所有路径的权值和不会大于longlong,所以维护路径权值和然后除以总方案数即可

对于每个节点,维护以下信息

1.s:子树内的路径权值和
2.sz:子树大小
3.sum:子树的点权和
4.num:作为左/右子树时的贡献(每个节点被计算的次数不同)

对于计算一颗子树的s
左子树会被计算szrs+1sz_{rs}+1szrs+1遍,右子树会被计算szls+1sz_{ls}+1szls+1遍,还有当前节点会被计算szls×szrssz_{ls}\times sz_{rs}szls×szrs

那么有sx=sls+srs+(szls+1)×numrs,1+(szrs+1)×numls,0+vx×(szls+1)∗(szrs+1)s_x = s_{ls} + s_{rs} + (sz_{ls} + 1) \times num_{rs,1} + (sz_{rs} + 1) \times num_{ls,0} + v_x \times (sz_{ls} + 1) * (sz_{rs} + 1)sx=sls+srs+(szls+1)×numrs,1+(szrs+1)×numls,0+vx×(szls+1)(szrs+1)

对于计算num,当作为左子树时,左子树的贡献不变,而每一次计算左子树时右子树和当前点也会被计算,所以要加上(szls+1)×(sumrs+vx)(sz_ls+1)\times (sum_rs + v_x)(szls+1)×(sumrs+vx),作为右子树时同理

其他信息就很好维护了,对此建立LCT即可


代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 50010
using namespace std;
ll n, m, x, y, z, nm[N];
struct LCT
{#define ls son[x][0]#define rs son[x][1]ll v[N], s[N], p[N], pn[N], fa[N];ll sz[N], sum[N], num[N][2], son[N][2];bool NR(ll x){return fa[x] && (son[fa[x]][0] == x || son[fa[x]][1] == x);}bool IRS(ll x){return son[fa[x]][1] == x;}void push_up(ll x){s[x] = s[ls] + s[rs] + (sz[ls] + 1) * num[rs][1] + (sz[rs] + 1) * num[ls][0] + v[x] * (sz[ls] + 1) * (sz[rs] + 1);num[x][0] = num[ls][0] + (v[x] + sum[rs]) * (sz[ls] + 1) + num[rs][0];num[x][1] = num[rs][1] + (v[x] + sum[ls]) * (sz[rs] + 1) + num[ls][1];sum[x] = sum[ls] + sum[rs] + v[x];sz[x] = sz[ls] + sz[rs] + 1;return;}void pushr(ll x){swap(ls, rs);swap(num[x][0], num[x][1]);//翻转时作为左/右子树的贡献会改变p[x] ^= 1;return;}void push_add(ll x, ll y){s[x] += nm[sz[x]] * y;//nm为所有方案下的点数和,在下文计算到num[x][0] += sz[x] * (sz[x] + 1) / 2 * y;//在维护时会计算到的次数num[x][1] += sz[x] * (sz[x] + 1) / 2 * y;sum[x] += sz[x] * y;v[x] += y;pn[x] += y;return; }void push_down(ll x){if (p[x]){if (ls) pushr(ls);if (rs) pushr(rs);p[x] = 0;}if (pn[x]){if (ls) push_add(ls, pn[x]);if (rs) push_add(rs, pn[x]);pn[x] = 0;}return;}void push_hall(ll x){if (NR(x)) push_hall(fa[x]);push_down(x);return;}void rotate(ll x){ll y = fa[x], z = fa[y], k = IRS(x), g = son[x][!k];if (NR(y)) son[z][IRS(y)] = x;if (g) fa[g] = y;son[x][!k] = y;son[y][k] = g;fa[y] = x;fa[x] = z;push_up(y);return;}void Splay(ll x){push_hall(x);while(NR(x)){if (NR(fa[x])){if (IRS(x) == IRS(fa[x])) rotate(fa[x]);else rotate(x);}rotate(x);}push_up(x);return;}void access(ll x){for (ll y = 0; x; x = fa[y = x])Splay(x), rs = y, push_up(x);return;}void make_root(ll x){access(x);Splay(x);pushr(x);return;}ll find_root(ll x){access(x);Splay(x);while(ls) push_down(x), x = ls;Splay(x);return x;}bool Split(ll x, ll y){make_root(x);if (find_root(y) != x) return 0; Splay(y);return 1;}void link(ll x, ll y){make_root(x);if (find_root(y) != x) fa[x] = y;return;}void cut(ll x, ll y){make_root(x);if (find_root(y) == x && fa[y] == x && !son[y][0]){fa[y] = rs = 0;push_up(x);}return;}
}T;
ll gcd(ll x, ll y)
{if (!y) return x;return gcd(y, x % y);
}
void solve(ll x, ll y)
{ll z = gcd(x, y);printf("%lld/%lld\n", x / z, y / z);return;
}
int main()
{scanf("%lld%lld", &n, &m);nm[1] = 1;for (ll i = 2; i <= n; ++i)nm[i] = nm[i - 1] + i * (i + 1) / 2;for (ll i = 1; i <= n; ++i)scanf("%lld", &T.v[i]);for (ll i = 1; i < n; ++i){scanf("%lld%lld", &x, &y);T.link(x, y);}while(m--){scanf("%lld%lld%lld", &z, &x, &y);if (z == 1) T.cut(x, y);else if (z == 2) T.link(x, y);else if (z == 3){scanf("%lld", &z);if (T.Split(x, y)) T.push_add(y, z);}else{if (!T.Split(x, y)) puts("-1");else solve(T.s[y], T.sz[y] * (T.sz[y] + 1) / 2);}}return 0;
}

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

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

相关文章

P6329-[模板]点分树 | 震波

正题 题目链接:https://www.luogu.com.cn/problem/P6329 解题思路 给出nnn个点的一棵树&#xff0c;每个点有权值&#xff0c;有mmm次操作 修改一个点xxx的权值为yyy询问距离点xxx不超过kkk的所有点点权和 解题思路 点分树的模板题&#xff0c;先点分治构造出点分树&#x…

Codeforces Round #660 (Div. 2)

A - Captain Flint and Crew Recruitment 刚开始还想筛法求质数&#xff0c;最后发现是个脑筋急转弯 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #define debug(x) cout<<#x<<": "<<x<<" " #include<ios…

[译]ABP vNext介绍

译者注ASP.NET Boilerplate是.Net平台非常优秀的一个开源Web应用程序框架,在国内也有大量的粉丝.近日, 本人在github上闲逛, 发现ASP.NET Boilerplate团队又悄悄的建立了一个新项目: ABP vNext从名称可以看出来, 这是ASP.NET Boilerplate的下一代框架. 那么, 为什么要开发这个新…

[HAOI2008]玩具取名

[HAOI2008]玩具取名 文章目录题目描述输出描述:题解代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 某人有一套玩具&#xff0c;并想法给玩具命名。首先他选…

【KMP】重复子串(ybtoj KMP-2)

正题 ybtoj KMP-2 题目大意 问你一个字符串最多由多少个相同的字符串组合而成 解题思路 如下图&#xff0c;先用KMP求出nx数组&#xff0c;那么有1∼nxn1\sim nx_n1∼nxn​和(n−nxn)∼n(n-nx_n)\sim n(n−nxn​)∼n相匹配 不难推出1∼(n−nxn)1\sim (n-nx_n)1∼(n−nxn​)…

P6624-[省选联考2020A卷]作业题【矩阵树定理,欧拉反演】

正题 题目链接:https://www.luogu.com.cn/problem/P6624 题目大意 nnn个点的一张图&#xff0c;每条边有权值&#xff0c;一棵生成树的权值是所有边权和乘上边权的gcdgcdgcd&#xff0c;即 val(T)(∑i1n−1wei)gcd⁡(we1,we2,…,wen−1)val(T)\left(\sum\limits_{i1}^{n-1} w_…

C# 8小特性

对于C# 8&#xff0c;有吸引了大多数注意力的重大特性&#xff0c;如默认接口方法和可空引用&#xff0c;也有许多小特性被考虑在内。本文将介绍几例可能加入C#未来版本的小特性。新的赋值运算符&#xff1a;&&和||从第一个版本开始&#xff0c;C#就支持把等号和另外一…

[HAOI2016]字符合并(ing)

[HAOI2016]字符合并 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 有一个长度为 n 的 01 串&#xff0c;你可以每次将相邻的 k 个字符合并&#xff0c;得到一个新的字符并…

AtCoder Beginner Contest 174 总结

这次做了ABDF。我也不知道我怎么做的&#xff08;乱做-.- A - Air Conditioner 签到题1 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #define debug(x) cout<<#x<<": "<<x<<" " #include<iostream> #…

【KMP】周期长度和(luogu 3435/ybtoj KMP-3)

正题 luogu 3435 ybtoj KMP-3 题目大意 定义S的proper前缀为S中非空且len<|S|的前缀&#xff0c;若Q是A的proper前缀&#xff0c;且A是QQ的前缀 现在问你字符串S所有前缀的最大周期之和 解题思路 如上图&#xff0c;对于一个字符串S&#xff0c;如果有周期Q&#xff0c;那…

P6097-[模板]子集卷积

正题 题目链接:https://www.luogu.com.cn/problem/P6097 题目大意 长度为2n2^n2n的序列a,ba,ba,b求一个ccc满足 ck∑i∣jk,i&j∅aibjc_k\sum_{i|jk,i\&j\varnothing}a_i\times b_jck​i∣jk,i&j∅∑​ai​bj​ 解题思路 从炫酷反演魔术过来的&#xff0c;顺便写…

dotnet core 开发无缝兼容Http和Websocket协议的接口服务

在应用接口开发中往往要针对不同协义开发相应的代理服务&#xff0c;但对于Websocket和http这两种协议来说就有些不同&#xff0c;从实现上来看Websocket可以说是Http的升级子协议&#xff0c; 两者在协议处理上基本一致&#xff0c;具体可以在解释Body上有所不同。FastHttpApi…

【KMP】子串拆分(ybtoj KMP-4)

正题 ybtoj KMP-4 题目大意 给出字符串S&#xff0c;问你有多少个子串满足ABA的形式&#xff0c;且∣A∣⩾k,∣B∣⩾1|A|\geqslant k,|B|\geqslant 1∣A∣⩾k,∣B∣⩾1 解题思路 可以先枚举左端点&#xff0c;然后跑KMP&#xff0c;使其满足左右两个A&#xff0c;然后判断A,…

[SDOI2008]SUE的小球

[SDOI2008]SUE的小球 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 Sue和Sandy最近迷上了一个电脑游戏&#xff0c;这个…

Codeforces Round #661 (Div. 3)

A - Remove Smallest 排个序&#xff0c;如果相邻的数大于一就不满足题意 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #define debug(x) cout<<#x<<": "<<x<<" " #include<iostream> #include<alg…

centos7 lldb 调试netcore应用的内存泄漏和死循环示例(dump文件调试)

写个demo来玩一玩linux平台下使用lldb加载sos来调试netcore应用。当然&#xff0c;在真实的产线环境中需要分析的数据和难度远远高于demo所示&#xff0c;所以demo的作用也仅仅只能起到介绍工具的作用。通常正常情况下&#xff0c;分析个几天才能得出一个结论的的结果都还是比较…

P4450-双亲数,P5221-Product,P6055-[RC-02]GCD【莫比乌斯反演,杜教筛】

除了最后一题都比较简单就写一起了 P4450-双亲数 题目链接:https://www.luogu.com.cn/problem/P4450 题目大意 给出A,B,dA,B,dA,B,d求有多少对(a,b)(a,b)(a,b)满足gcd(a,b)dgcd(a,b)dgcd(a,b)d且a∈[1,A],b∈[1,B]a\in[1,A],b\in[1,B]a∈[1,A],b∈[1,B] 解题思路 很显然的…

【Trie】最大异或对(ybtoj Trie-2)

正题 ybtoj Trie-2 题目大意 给你n个数&#xff0c;选择2个&#xff0c;使其异或值最大 解题思路 对于每个数的二进制建立Trie&#xff0c;然后每个数在Trie中搜索&#xff0c;每次尽量走不同方向 代码 #include<cstdio> #include<cstring> #include<iostrea…

[SCOI2003]字符串折叠

[SCOI2003]字符串折叠 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 折叠的定义如下&#xff1a; 一个字符串可以看成它自身的折叠。记作S S X(S)是X(X>1)个S连接在一…

Codeforces Round #662 (Div. 2)

就写了两个题&#xff0c;以为要掉分&#xff0c;结果早上起来发现还上分了&#xff08;说明wtcl A - Rainbow Dash, Fluttershy and Chess Coloring 无论边长是奇数还是偶数&#xff0c;考虑每次操作最外层的一圈&#xff0c;一个人操作一圈的一般&#xff0c;然后另一个人就…