【SPOJ2666】QTree4【链分治】

传送门

题意:给一棵带边权的树,每个点开始时为白色,维护两种操作:

1.改变一个点的颜色(白变黑,黑变白)
2.询问最远的两个白点之间的距离

树分治国集论文

链分治的本质其实就是树链剖分。它们的区别是树剖维护路径询问,链分治维护全局路径。

动态点分治需要重新建一棵树,而链分治分出来的是链,本身就可以用数据结构维护。所以链分治本身就可以资瓷修改。

对于每一条链单独用数据结构维护与当前链有交集的路径信息。

对于本题,先树链剖分

Di,Di′D_i,D_i'Di,Di为节点iii沿虚边往下走到某个白点的最长和次长长度。如果不存在,记为−INF-INFINF

用线段树维护一条链。对于一条链上的一个区间[L,R][L,R][L,R]

lmax=max{dist(L,i)+Di}lmax=max\{dist(L,i)+D_i\}lmax=max{dist(L,i)+Di}

rmax=max{Di+dist(i,R)}rmax=max\{D_i+dist(i,R)\}rmax=max{Di+dist(i,R)}

即:lmaxlmaxlmax表示LLL沿这条链往下走(可以不走),在[L,R][L,R][L,R]中的某个点拐出去,往下走(可以不走)到某个白点经过的最长长度。注意没有要求起点是白色rmaxrmaxrmax同理。

再记录ansansans表示有交集的最长长度

然后用类似最大子段和的方式合并。

对于一个线段树节点ppp,左右儿子lc,rclc,rclc,rc

lmax[p]=max{lmax[lc],dist(L,mid+1)+lmax[rc]}lmax[p]=max\{lmax[lc],dist(L,mid+1)+lmax[rc]\}lmax[p]=max{lmax[lc],dist(L,mid+1)+lmax[rc]}

rmax[p]=max{rmax[lc]+dist(mid,R),rmax[rc]}rmax[p]=max\{rmax[lc]+dist(mid,R),rmax[rc]\}rmax[p]=max{rmax[lc]+dist(mid,R),rmax[rc]}

ans[p]=max{ans[lc],ans[rc],rmax[lc]+dist(mid,mid+1)+lmax[rc]}ans[p]=max\{ans[lc],ans[rc],rmax[lc]+dist(mid,mid+1)+lmax[rc]\}ans[p]=max{ans[lc],ans[rc],rmax[lc]+dist(mid,mid+1)+lmax[rc]}

边界:当L=RL=RL=R,设当前点为iii

iii是白点

lmax=rmax=max{Di,0}lmax=rmax=max\{D_i,0\}lmax=rmax=max{Di,0}

ans=max{0,Di,Di+Di′}ans=max\{0,D_i,D_i+D_i'\}ans=max{0,Di,Di+Di}

否则

lmax=rmax=Dilmax=rmax=D_ilmax=rmax=Di

ans=Di+Di′ans=D_i+D_i'ans=Di+Di

最后需要维护Di,Di′D_i,D_i'Di,Di

iii是白点,jjjiii的轻儿子

Di=max{0,w(i,j)+lmax[j]}D_i=max\{0,w(i,j)+lmax[j]\}Di=max{0,w(i,j)+lmax[j]}

iii是黑点

Di=w(i,j)+lmax[j]D_i=w(i,j)+lmax[j]Di=w(i,j)+lmax[j]

然后用个堆之类的瞎维护即可

然而写起来十分精神污染

有一个常用的转换方式
在这里插入图片描述在这里插入图片描述
红色边权值为000

这样这棵树变成了二叉树,且两两之间的距离不变。也就是说和原来的树是等效的。

有什么用呢?

这样一个节点最多有一个重儿子一个轻儿子,Di′D_i'Di永远为−INF-INFINFDiD_iDi可以直接计算,大大降低编程复杂度。当然好不好调是另外一回事

最后答案用multisetmultisetmultiset暴艹即可

复杂度O(nlogn2)O(nlog_n^2)O(nlogn2)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <set>
#define MAXN 200005
#define INF 0x3f3f3f3f
using namespace std;
inline int read()
{int ans=0,f=1;char c=getchar();while (c<'0'||c>'9'){if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}return f*ans;
}
inline char gal()
{char c=getchar();while (c<'A'||c>'Z') c=getchar();return c;
}
int n;
struct edge
{int u,v,w;
}e[MAXN];
int head[MAXN],nxt[MAXN],cnt;
void addnode(int u,int v,int w)
{e[++cnt]=(edge){u,v,w};nxt[cnt]=head[u];head[u]=cnt;
}
int son[MAXN][2];
int fa[MAXN],dep[MAXN],cost[MAXN],col[MAXN];
void dfs(int u)
{int las=u;for (int i=head[u];i;i=nxt[i])if (!dep[e[i].v]){fa[fa[e[i].v]=++n]=las;dep[e[i].v]=dep[u]+1;cost[e[i].v]=e[i].w;dfs(son[las=son[las][las!=u]=n][0]=e[i].v);}
}
int siz[MAXN],dis[MAXN],tp[MAXN],bt[MAXN];
int dfn[MAXN],pos[MAXN],tim;
void Dfs(int u)
{if (!u) return;siz[u]=1;Dfs(son[u][0]),Dfs(son[u][1]);siz[u]+=siz[son[u][0]]+siz[son[u][1]];if (siz[son[u][0]]<siz[son[u][1]]) swap(son[u][0],son[u][1]);
}
multiset<int> re;
int rt[MAXN],tot;
int ch[MAXN<<2][2],lmax[MAXN<<2],rmax[MAXN<<2],ans[MAXN<<2];
inline int d(const int& x)
{if (!son[x][1]) return col[x]? 0:-INF;if (col[x]) return max(cost[son[x][1]]+lmax[rt[son[x][1]]],0);return cost[son[x][1]]+lmax[rt[son[x][1]]];
}
#define lc ch[p][0]
#define rc ch[p][1]
inline void update(const int& p,const int& l,const int& r)
{int mid=(l+r)>>1;lmax[p]=max(lmax[lc],dis[pos[mid+1]]-dis[pos[l]]+lmax[rc]);rmax[p]=max(rmax[lc]+dis[pos[r]]-dis[pos[mid]],rmax[rc]);ans[p]=max(max(ans[lc],ans[rc]),rmax[lc]+cost[pos[mid+1]]+lmax[rc]);
}
void build(int& p,int l,int r)
{p=++tot;if (l==r){if (col[pos[l]]) ans[p]=lmax[p]=rmax[p]=max(0,d(pos[l]));else lmax[p]=rmax[p]=d(pos[l]),ans[p]=-INF;return;}int mid=(l+r)>>1;build(lc,l,mid);build(rc,mid+1,r);update(p,l,r);
}
void modify(int p,int l,int r,int k)
{if (l==r){if (col[pos[l]]) ans[p]=lmax[p]=rmax[p]=max(0,d(pos[l]));else lmax[p]=rmax[p]=d(pos[l]),ans[p]=-INF;return;}int mid=(l+r)>>1;if (k<=mid) modify(lc,l,mid,k);else modify(rc,mid+1,r,k);update(p,l,r);
}
void DFS(int u,int t)
{if (!u) return;dis[u]=dis[fa[u]]+cost[u];bt[tp[u]=t]=pos[dfn[u]=++tim]=u;DFS(son[u][0],t);DFS(son[u][1],son[u][1]);if (u==t) build(rt[u],dfn[u],dfn[bt[u]]),re.insert(ans[rt[u]]);
}
int main()
{freopen("test.in","r",stdin);n=read();int cnt=n;for (int i=1;i<=n;i++) col[i]=1;for (int i=1;i<n;i++){int u,v,w;u=read(),v=read(),w=read();addnode(u,v,w),addnode(v,u,w);}dep[1]=1;dfs(1);Dfs(1);DFS(1,1);for (int i=read();i;--i){if (gal()=='A') cnt? printf("%d\n",max(0,*re.rbegin())):puts("They have disappeared.");else{int x=read();for ((col[x]^=1)? ++cnt:--cnt;x;re.erase(re.find(ans[rt[tp[x]]])),modify(rt[tp[x]],dfn[tp[x]],dfn[bt[tp[x]]],dfn[x]),re.insert(ans[rt[tp[x]]]),x=fa[tp[x]]);}}return 0;
}

做这种题一定要先理清思路,弄懂定义再开始码,不要边想边写

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

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

相关文章

2021牛客第五场 I.Interval Queries-回滚莫队

如图&#xff1a;一道很裸的回滚莫队&#xff0c;注意加入的操作和回滚的操作就好了。 #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #i…

Linux下搭建asp.net运行环境

最近有个项目&#xff0c;是在Windows平台下开发的&#xff0c;需要把 asp.net web应用移植到 CentOS下&#xff0c;甚是头疼&#xff1b;翻阅资料&#xff0c;发现Jexus是个可行的方案&#xff0c;下面是官方对Jexus的定义&#xff1a;什么是JexusJexus是一款Linux平台上的高性…

Codeforces Round #736 (Div. 2)E. The Three Little Pigs-长除法求多项式系数

https://codeforces.com/contest/1549/problem/E 题目大意自己悟吧&#xff0c;不解释了。 这题在赛时我想的是fft&#xff0c;但是题解说不用fft就能求出多项式的系数&#xff0c;fft在这题时间复杂度有点高。 使用多项式长除法就能求出系数&#xff0c;k^x的系数就是抓x个p…

在 Asp.Net Core WebAPI 中防御跨站请求伪造攻击

什么是跨站请求伪造跨站请求伪造&#xff08;英语&#xff1a;Cross-site request forgery&#xff09;&#xff0c;也被称为 one-click attack 或者 session riding&#xff0c;通常缩写为 CSRF 或者 XSRF&#xff0c; 是一种挟制用户在当前已登录的Web应用程序上执行非本意的…

HDU2021多校第五天 1009 Array-树状数组求二阶前缀和

https://acm.hdu.edu.cn/showproblem.php?pid7020 题目大意&#xff1a;求出区间众数严格大于区间一半大小的子区间的数量。 思路&#xff1a;先对每一个数求出对应的位置排列&#xff0c;S[j]代表1-有多少个i&#xff0c;易得s[r]-s[l]>r-l-(s[r]-s[l])的时候子区间{l1&a…

C# 8 新增小功能

尽管 C# 8 应该会在今年发布&#xff0c;并且 C# 8.x 和 9 的路线图也开始形成&#xff0c;但是&#xff0c;微软正在继续审查下一个版本的特性。目标类型表达式假设我们有 A、B 和 C 三种类型&#xff0c;其中类型 B 和 C 是类型 A 的子类型。如果我们使用如下所示的语句&…

2021HDU多校第五场1004 Another String-双指针

https://acm.hdu.edu.cn/showproblem.php?pid7015 题意&#xff1a;对于每次以i来分割字符串&#xff0c;计算两个分割串的子串的k-匹配的数量。 思路&#xff1a;当我们计算到ans[i]是&#xff0c;我们可以当成从ans[i-1]加上【1-i】字符串和【i1&#xff0c;n】的k-匹配数量…

C# 默认接口方法更新完成,很多细节问题尚待解决

随着对默认接口方法的支持越来越接近完成&#xff0c;一些潜在的问题被提了出来。虽然已经完成了很多工作&#xff0c;但这是一个复杂的特性&#xff0c;许多细节问题还没有解决。但首先&#xff0c;这里有一些已解决的问题。接口允许使用 static 和 const 字段了。除 和! 之外…

2021HDU多校第九场1008HDU7073 Integers Have Friends 2. 随机化

HUD地址&#xff1a;https://acm.hdu.edu.cn/showproblem.php?pid7073 题目大意&#xff1a;选择数组中最多的数&#xff0c;使得他们模m同余&#xff08;m>2&#xff09;。求最大的数量。 思路&#xff1a;然后我们全选奇数或者全选偶数的话&#xff0c;那么我们的答案是…

一个引发程序员们干架的问题

这里是Z哥的个人公众号每周五早8点 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「77」篇原创敬上在一个分布式系统的开发团队中&#xff0c;有一些问题是很容易产生程序员之间矛盾的。其中之一就是「业务归属」&#xff0c;就是当新加/修改一个业务的时候&a…

微服务探索与实践—服务注册与发现

前言微服务从大规模使用到现在已经有很多年了&#xff0c;从之前的探索到一步步的不断完善与成熟&#xff0c;微服务已经成为众多架构选择中所必须面对的一个选项。服务注册与发现是相辅相成的&#xff0c;所以一般会合起来思索。其依托组件有很多&#xff0c;比如Zookeeper,Co…

微服务探索与实践—总述

背景软件开发是一个不断发展的过程&#xff0c;从当初的面向过程为主到如今的面向对象的开发&#xff0c;软件开发者不断探索与实践更加符合时代发展要求的开发模式与架构思想&#xff0c;而这&#xff0c;也在极大程度上提高了软件开发的效率。微服务是一种架构模式或者说是架…

这周,全球首个IT技术全中文免费学习平台诞生了!太惊艳!

本周三的Developer Wednesday为大家揭秘了Microsoft Learn网站的全新学习模式一时间Microsoft Learn圈粉无数如果你正在为错过直播而暴风哭泣等一等&#xff0c;看这里&#xff01;全程高清回播将为你持续解密这一次你一定不可以再错过了哦&#xff01;什么是Microsoft Learn&…

十分钟了解Kubernetes

何为Kubernetes?最简单的一句话来概括Kubernetes。它就是一套成熟的商用服务编排解决方案。Kubernetes定位在Paas层&#xff0c;重点解决了微服务大规模部署时的服务编排问题。Kubernetes组件介绍了解Kubernetes都是从Pod开始的。Pod是Kubernetes最小的调度单元&#xff0c;所…

【CF1194E】Count The Rectangles【类扫描线】【单调性】【树状数组】

传送门 题意&#xff1a;给定NNN条与坐标轴平行的线段&#xff0c;保证不垂直的线段没有交点&#xff0c;求一共构成多少个矩形&#xff08;以线段交点为顶点&#xff09;。 1≤N≤50001\leq N\leq50001≤N≤5000 显然是个数据结构乱搞题。 直觉告诉我们先枚举一条线段。 假…

.NET Core 的过去、现在和未来

在最新的微软 Build 大会主题网站上&#xff0c;微软.NET 程序经理 Scott Hunter 发表了一篇文章&#xff0c;指出.NET Core 是.NET 的未来。去年&#xff0c;微软就已经确认 Visual Studio Live 中的.NET 框架将会被.NET Core 取代。将.NET Core 作为开源开发技术栈在 2014 年…

Visual Basic 兴衰记

这是一篇暴露年龄的文章。为什么这么说&#xff1f;因为现在年轻的程序员可能没有接触过当年红极一时的 Visual Basic。28 年前的 1991 年 4 月&#xff0c;Microsoft 发布了 Visual Basic 1.0 for Windows&#xff0c;次年 9 月&#xff0c;发布了 Visual Basic 1.0 for DOS。…

函数式编程里的Materialization应该翻译成什么?

Materialization是函数式编程里的一个专业术语, 用于特指函数式编程中查询被实际执行并生成结果的这一过程.首先, 搜了一下中文资料, 暂时没有对该词的中文翻译, CSDN\博客园\阿里云上所有关于它的文档都没有做中文翻译, 直接沿用这个英文单词.难道轮到我来创造这个词的中文翻…

Ozon Tech Challenge 2020 (Div.1 + Div.2) E.Kuroni and the Score Distribution 构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 不难想到&#xff0c;长度为nnn的数组最多的满足条件的三元组序列是1,2,3....,n1,2,3....,n1,2,3....,n&#xff0c;对于每一个位置贡献为i−12\frac{i-1}{2}2i−1​&#xff0c;那么如果m…

Exceptionless(二) - 使用进阶

作者&#xff1a;markjiang7m2原文地址&#xff1a;https://www.cnblogs.com/markjiang7m2/p/11100563.html官网地址&#xff1a;http://letyouknow.net在上一篇文章Exceptionless - .Net Core开源日志框架中就说到如何对Exceptionless进行本地化部署&#xff0c;不过我也跟大家…