P4842 城市旅行(拆贡献 + LCT)

2024-09-05 02:44
文章标签 p4842 lct 旅行 贡献 城市

本文主要是介绍P4842 城市旅行(拆贡献 + LCT),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://www.luogu.com.cn/problem/P4842

发现题目就是要维护一个LCT,然后我们只要把pushup写成功了就行。

那我们现在就不管LCT了,就单纯想用一棵二叉查找树怎么维护。分母是好搞的,分子我们要想点办法。

考虑右子树对左子树的贡献,我们假设处理出一个 L [ k ] L[k] L[k] 表示左子树中每个值乘以左边界的可选数量,我们现在再乘上右子树的大小就成功了。

那么pushup就很好写了,现在就是整棵树加 x x x 的问题,但这个东西看起来很复杂,但其实我们只需要把转移系数仔细算算就出来了。

一个要注意的地方是,整体reverse的时候要交换 L [ k ] , R [ k ] L[k],R[k] L[k],R[k]

//5k
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL#define debug(...) fprintf(stdout, ##__VA_ARGS__)#define debag(...) fprintf(stderr, ##__VA_ARGS__)
#else#define debug(...) void(0)#define debag(...) void(0)
#endif
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
int F1(int n) { return (n * (n + 1) / 2 + n * (n + 1) * (2 * n + 1) / 6) / 2; }
int F3(int n) { return n * (n + 1) * (n + 2) / 6; }
int F2(int n) { return n * (n + 1) / 2; }
//#define M
//#define mo
#define N 50010
int n, m, i, j, k, T;namespace LCT {
#define ls(x) (son[x][0])
#define rs(x) (son[x][1])int i, j, k; int a[N], s[N], L[N], R[N], ans[N], tag[N], son[N][2], w[N]; int rev[N], fa[N]; void Add(int k, int x) {a[k] += x; s[k] += x * w[k]; tag[k] += x; ans[k] += x * F3(w[k]); L[k] += x * F2(w[k]); R[k] += x * F2(w[k]); }int zh(int x) {return rs(fa[x]) == x; }void push_down(int k) {if(rev[k]) {swap(ls(k), rs(k)); swap(L[k], R[k]); if(ls(k)) rev[ls(k)] ^= 1; if(rs(k)) rev[rs(k)] ^= 1; rev[k] = 0; }if(tag[k]) {if(ls(k)) Add(ls(k), tag[k]); if(rs(k)) Add(rs(k), tag[k]); tag[k] = 0; }}void push_up(int k) {if(!k) return ; int l = ls(k), r = rs(k); push_down(k); if(l) push_down(l); if(r) push_down(r); s[k] = s[l] + s[r] + a[k]; w[k] = w[l] + w[r] + 1; ans[k] = ans[l] + ans[r] + a[k] * (w[l] + 1) * (w[r] + 1); ans[k] += L[l] * (1 + w[r]) + R[r] * (1 + w[l]); L[k] = L[l] + L[r] + (a[k] + s[r]) * (w[l] + 1); R[k] = R[r] + R[l] + (a[k] + s[l]) * (w[r] + 1); }bool isRoot(int x) {if(!fa[x]) return x; return ls(fa[x]) != x && rs(fa[x]) != x; }void Rotate(int x) {int y = fa[x], z = fa[y]; int k = zh(x), w = son[x][k ^ 1]; 
//		push_up(z); push_up(y); push_up(x); push_up(w); if(z && !isRoot(y)) son[z][zh(y)] = x; if(w) son[y][k] = w, fa[w] = y; else son[y][k] = 0; fa[x] = z; fa[y] = x; son[x][k ^ 1] = y; push_up(w); push_up(y); push_up(x); push_up(z); }void Splay(int x) {stack<int>sta; sta.push(x); for(int y = x; !isRoot(y); y = fa[y]) sta.push(fa[y]); while(!sta.empty()) push_up(sta.top()), sta.pop(); while(!isRoot(x)) {int y = fa[x]; if(!isRoot(y)) {if(zh(x) == zh(y)) Rotate(y); else Rotate(x); }Rotate(x); }}void access(int x) {for(int y = 0; x; y = x, x = fa[x]) {Splay(x); rs(x) = y; push_up(y); push_up(x); }}void makeRoot(int x) {access(x); Splay(x); rev[x] ^= 1; push_up(x); }int findRoot(int x) {access(x); Splay(x); while(push_up(x), ls(x)) x = ls(x); Splay(x); return x; }void Link(int x, int y) {makeRoot(x); fa[x] = y; }void Cut(int x, int y) {makeRoot(x); access(y); Splay(y); fa[x] = son[y][0] = 0; push_up(y); push_up(x); }bool check(int x, int y) {makeRoot(x); return findRoot(y) == x; }bool find_edge(int x, int y) {makeRoot(x); access(y); Splay(y); return w[y] == 2; }pair<int, int> Qans(int x, int y) {makeRoot(x); access(y); Splay(y); 
//		for(i = 1; i <= n; ++i) push_down(i), push_up(i); 
//		for(i = 1; i <= n; ++i) push_down(i), push_up(i); return {ans[y], w[y]}; }void print() {#ifdef LOCALfor(int i = 0; i <= n; ++i) debug("> %lld %lld(%lld) [%lld %lld] %lld %lld %lld %lld %lld\n", i, fa[i], (int)isRoot(i), ls(i), rs(i), w[i], s[i], L[i], R[i], ans[i]); debug("-------------\n"); #endif}
}signed main()
{#ifdef LOCALfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);#endif
//	srand(time(NULL));
//	T=read();
//	while(T--) {
//
//	}int op, u, v; n = read(); m = read(); for(i = 1; i <= n; ++i) LCT :: w[i] = 1; for(i = 1; i <= n; ++i) {k = read(); LCT :: Add(i, k); } for(i = 1; i < n; ++i) {u = read(); v = read(); LCT :: Link(u, v); }
//	LCT :: print(); for(i = 1; i <= m; ++i) {op = read(); u = read(); v = read(); 
//		assert(u != v); if(op == 1) {if(u == v) continue; if(LCT :: find_edge(u, v)) LCT :: Cut(u, v); }if(op == 2) {			if(u == v) continue; if(!LCT :: check(u, v)) LCT :: Link(u, v); }if(op == 3) {k = read(); if(LCT :: check(u, v)) {LCT :: makeRoot(u); LCT :: access(v); LCT :: Splay(u); LCT :: Add(u, k); }}if(op == 4) {if(!LCT :: check(u, v)) { printf("-1\n"); continue; }auto t = LCT :: Qans(u, v); debug("[%lld %lld] %lld\n", t.fi, t.se, F2(t.se)); t.se = F2(t.se); k = __gcd(t.fi, t.se); t.fi /= k; t.se /= k; printf("%lld/%lld\n", t.fi, t.se); }LCT :: print(); 
//		printf("===============\n"); }return 0;
}

这篇关于P4842 城市旅行(拆贡献 + LCT)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137749

相关文章

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

社交平台找旅游搭子一起旅行靠谱吗?答案是不要太爽!

哈喽小伙伴们,今天要跟大家分享一个超级棒的小程序——咕哇找搭子!作为一个热爱自由行的人,最头疼的就是找不到志同道合的小伙伴。但自从用了这个咕哇小程序后,一切都变得简单又充满乐趣啦!🎉 上个月,我计划去云南旅行,就试着在咕哇上发布了我的行程信息。没想到很快就收到了几位朋友的回应,其中一位叫小莲的朋友特别投缘。我们不仅目的地一样,就连兴趣爱好都出奇地相似,于是我们就决定一起出发啦!👭

旅行商问题 | Matlab基于混合粒子群算法GA-PSO的旅行商问题TSP

目录 效果一览基本介绍建模步骤程序设计参考资料 效果一览 基本介绍 混合粒子群算法GA-PSO是一种结合了遗传算法(Genetic Algorithm, GA)和粒子群优化算法(Particle Swarm Optimization, PSO)的优化算法。在解决旅行商问题(Traveling Salesman Problem, TSP)时,这种混合算法可以结合两种算法的优点

2024年上海松江启动建筑绿色低碳发展专项检查,共绘城市节能新篇章

2024年9月4日,2024年度松江区建筑工程绿色低碳发展工作专项检查会议正式开展,会议内容主要围绕以下三点, 1、《关于开展 2024年度本市建筑领域绿色低碳发展工作监督检查的通知》宣贯。 2、分项计量、能效测评工作验收要求介绍。 3、专项检查工作安排。 我国在早期没有高度重视建筑物的环保节能,造成了过去30年内竣工的建筑绝大多数是高能耗工程建筑,这类工程建筑在未来几十年里将耗费许多能源

五星级可视化页面(06):城市鸟瞰页面,居高临下,高屋建瓴。

本期分享城市鸟瞰图的可视化大屏幕,这类场景一般在智慧城市和城市治理可视化中常用。

利用高德API获取整个城市的公交路线并可视化(四)

副标题:公共汽电车站点覆盖率——以厦门市公交线路为例 书接上回,我们有了公交的线路、站点数据,并同时对数据质量进行了校验,但是不同城市情况不同,需要看当地对公交交通数据的开放程度,部分城市建设的有大数据平台,也可以检索到公共交通的一些标签数据,这篇文章我们来讨论一下公交覆盖率; 公交数据获取方式参考我上篇文章:利用高德API获取整个城市的公交路线并可视化(三)-CSDN博客 首先先根据行政区

【HDU】5333 Undirected Graph【LCT+BIT】

传送门:【HDU】5333 Undirected Graph my  code: my~~code: #pragma comment(linker, "/STACK:1024000000")#include <stdio.h>#include <string.h>#include <map>#include <algorithm>using namespace std ;typed

【HDU】5321 Beautiful Set【枚举k求贡献,欧拉函数应用】

传送门: 【HDU】5321 Beautiful Set my  code: my~~code: #include <stdio.h>#include <string.h>#include <vector>#include <algorithm>using namespace std ;typedef long long LL ;#define clr( a , x ) memset

SCI论文贡献写法

Arindam Dey: Conceptualization, Methodology, Formal analysis, Resources, Data curation, Supervision, Writing – original draft, Writing – review & editing, Project administration. Amit Barde: Writing –

可以进行非机动车违停、人员聚集、临街摆摊、垃圾满溢、烟雾火情等城市治理场景的智能识别的智慧城管开源了

智慧城管视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。 基于深度学习技术及强大的专家团队,针对多个工业垂类场景进行算法优化,打造最优的工业AI算法模型,提供更加精准的工业AI模型库,客户可直接选择适合自己业务场景的模型,快速实现业务落地