#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 150005
using namespace std; int n,m,val[maxn],tot[maxn],fa[maxn],sum[maxn],son[maxn][],bel[maxn],bel_[maxn];
bool rev[maxn]; struct date{
int isroot(int x){
return son[fa[x]][]!=x&&son[fa[x]][]!=x;
}
bool which(int x){
return son[fa[x]][]==x;
}
void update(int x){
sum[x]=tot[x];
if (son[x][]) sum[x]+=sum[son[x][]];
if (son[x][]) sum[x]+=sum[son[x][]];
}
void pushdown(int x){
if (!rev[x]) return;
swap(son[x][],son[x][]),rev[x]^=;
if (son[x][]) rev[son[x][]]^=;
if (son[x][]) rev[son[x][]]^=;
}
void relax(int x){
if (!isroot(x)) relax(fa[x]);
pushdown(x);
}
void rotata(int x){
int y=fa[x],d=which(x),dd=which(y);
if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
fa[son[x][d^]]=y,son[y][d]=son[x][d^];
fa[y]=x,son[x][d^]=y;
update(y);
}
void splay(int x){
relax(x);
while (!isroot(x)){
if (isroot(fa[x])) rotata(x);
else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
else rotata(x),rotata(x);
}
update(x);
}
int find(int x){
if (bel[x]!=x) bel[x]=find(bel[x]);
return bel[x];
}
int find_(int x){
if (bel_[x]!=x) bel_[x]=find_(bel_[x]);
return bel_[x];
}
void access(int x){
for (int p=;x;fa[x]=find(fa[x]),x=fa[x]){
splay(x);
son[x][]=p;
p=x;
update(x);
}
}
void make_root(int x){
access(x);
splay(x);
rev[x]^=;
}
void link(int x,int y){
make_root(x);
fa[x]=y;
}
void merge(int x,int y){
bel[x]=y;
if (x!=y) tot[y]+=tot[x];
pushdown(x);
if (son[x][]) merge(son[x][],y);
if (son[x][]) merge(son[x][],y);
}
void build(int x,int y){
if (x==y) return;
x=find(x),y=find(y);
int xx=find_(x),yy=find_(y);
if (xx!=yy) link(x,y),bel_[xx]=yy;
else{
make_root(x),access(y),splay(y),merge(y,y);
}
}
void change(int x,int y){
int t=find(x);
splay(t),tot[t]-=val[x],val[x]=y,tot[t]+=val[x],update(t);
}
void query(int x,int y){
x=find(x),y=find(y);
if (find_(x)!=find_(y)) printf("-1\n");
else make_root(x),access(y),splay(y),printf("%d\n",sum[y]);
}
}lct; int main(){
freopen("race.in","r",stdin);
freopen("race.out","w",stdout);
memset(rev,,sizeof(rev));
int op,u,v;
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&u),val[i]=tot[i]=sum[i]=u,rev[i]=fa[i]=son[i][]=son[i][]=,bel[i]=bel_[i]=i;
while (m--){
scanf("%d%d%d",&op,&u,&v);
if (op==) lct.build(u,v);
else if (op==) lct.change(u,v);
else lct.query(u,v);
}
return ;
}

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2959

题目大意:给定无向图,有n个节点,初始时节点之间没有边,节点的初始节点权值为val[i],有m个操作:

1.在a,b之间连一条无向边;

2.将节点a的权值改为b;

3.询问操作:给定a,b,要你给图中无向边定向,再寻找一条路径,满足路径上的节点权值之和最大,不一定是简单路径,即每个点可以经过多次,但权值只会算一次,若不存在这样的路径,则输出-1。

做法:如果没有操作1,我们可以把原图中的边双连通分量缩点,该点的权值为该边双连通分量中节点的权值之和,缩完点后,会变成一个森林,对于操作2与操作3,用树链剖分即可。

有了操作1,我们会想到用lct来维护,加入一条边后,如果不形成环,就加入,否则,将链上的点缩成一个点,用并查集维护即可。

注意:access的时候这能把双联通分量的代表点加入splay中,否则答案会重复算,具体见access过程。

由于这题卡常数,没有删边操作,在判断连通性时不能用find_root(x),应再用一个并查集来维护。

lct+并查集

bzoj2959: 长跑的更多相关文章

  1. [BZOJ2959]长跑——新技能:LCT+缩圈

    [BZOJ2959]长跑 试题描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘 ...

  2. BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)

    题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...

  3. bzoj2959: 长跑(LCT+并查集)

    题解 动态树Link-cut tree(LCT)总结 LCT常数大得真实 没有环,就是\(lct\)裸题吧 有环,我们就可以绕环转一圈,缩点 怎么搞? 当形成环时,把所有点的值全部加到一个点上,用并查 ...

  4. bzoj2959: 长跑 LCT+并查集+边双联通

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2959 题解 调了半天,终于调完了. 显然题目要求是求出目前从 \(A\) 到 \(B\) 的可 ...

  5. BZOJ3069: [Pa2011]Hard Choice 艰难的选择

    Description Byteasar是一个很纠结的人.每次他经过Bytetown的时候都知道有至少2条不同的路径可以选择,这导致他必须花很长时间来决定走哪条路.Byteasar最近听说了Bytet ...

  6. LCT总结——应用篇(附题单)(LCT)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--概念篇戳这里 题单 灰常感谢XZY巨佬提供的强力资磁!(可参考XZY巨佬的博客总结) 题单对于系 ...

  7. Link Cut Tree 总结

    Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...

  8. 一些$LCT$的瓜皮题目

    一些瓜皮 放几个比较优(she)秀(pi)的\(LCT\)题. 老惯例,每一题代码因为一些未知原因消失了(如果要的话私我好了,虽然会咕咕咕). 嘴巴\(AC\)真香! [SP16580] QTREE7 ...

  9. OI刷题录——hahalidaxin

    16-3-25  —— bzoj 2049 [Sdoi2008]Cave 洞穴勘测:LCT入门 bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊:LCT Tsinsen A1303. t ...

随机推荐

  1. SQL Server 2005、2008 的 datetime 值范围(转)

    SQL Server 2005.2008 的 datetime 最小值是:1753-01-01 00:00:00 最大值是:9999-12-31 23:59:59.997 这与 .NET 中的 Dat ...

  2. Stream 和 byte[]

    C# Stream 和 byte[] 之间的转换   一. 二进制转换成图片MemoryStream ms = new MemoryStream(bytes);ms.Position = 0;Imag ...

  3. FineUI大版本升级,外置ExtJS库、去AXD化、表格合计行、表格可编辑单元格的增删改、顶部菜单框架

    这是一篇很长的文章,在开始正文之前,请允许我代表目前排名前 20 中唯一的 .Net 开源软件 FineUI 拉下选票: 投票地址: https://code.csdn.net/2013OSSurve ...

  4. 重建中国.NET生态系统

    Neuzilla官方微信公众号:搜 架构师联盟 或 neuzilla 我是.NET铁杆粉丝,所以如果你要在评论里跟我撕逼.NET怎么怎么烂,Java.C++.PHP.JavaScript怎么怎么好,我 ...

  5. 用js转换joson返回数据库的时间格式为/Date(*************)/

    原理是取中间的毫秒数,再转换成js的Date类型 function ChangeDateFormat(val) { if (val != null) { var date = new Date(par ...

  6. Android开发遇到的坑(1):Java中List的安全删除问题

    在项目的开发过程中,一定少不了的是对Java集合中的List接触.项目中对List的删掉也是一种常见的操作,看上这个操作也没什么好说的样子,但是在项目开发中也是最容易出错的地方,特别是对于新手.有时候 ...

  7. HttpClient4.5 SSL访问工具类

    要从网上找一个HttpClient SSL访问工具类太难了,原因是HttpClient版本太多了,稍有差别就不能用,最后笔者干脆自己封装了一个访问HTTPS并绕过证书工具类. 主要是基于新版本Http ...

  8. SqlServer——批量插入数据

    像Major表里面批量插入数据演示: 代码如下: Declare @I int Set @I= Begin Tran InsertData: Insert into Major values(@I,' ...

  9. nodepad++快捷键收集

    Notepad++ 快捷键 大全Ctrl+C 复制Ctrl+X 剪切Ctrl+V 粘贴Ctrl+Z 撤消Ctrl+Y 恢复Ctrl+A 全选Ctrl+F 键查找对话框启动Ctrl+H 查找/替换对话框 ...

  10. 作业成绩 final-review 20161201-1203 15:05

    final-review阶段,20161201-20161203 15:05 final 评论II截止 20161204 09:00 申诉截止时间 20161207 12:00,微信联系杨贵福. 凡描 ...