#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. Java集合系列:-----------05LinkedList的底层实现

    前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类--LinkedList.和学习ArrayList一样,接下来呢,我们先对LinkedList ...

  2. jQuery动态产生的铵钮怎样实现事件处理

    在ASP.NET MVC环境中,实现一个小功能,就是希望使用jQuery动态一个铵钮,并让用户能执行这个铵钮的click事件.为了更好的理解与对比,Insus.NET在视图中先写一个静态的,执行相似的 ...

  3. Android属性(property)机制

    1. 属性简介 Android里有很多属性(property),每个属性都有一个名称和值,他们都是字符串格式.这些属性定义了Android系统的一些公共系统属性.比如: [dalvik.vm.dexo ...

  4. Qt中的qreal

    在桌面操作系统中(比如Windows, XNix等)qreal其实就是double类型:而在嵌入设备系统中,qreal则等同于float 类型.

  5. Jump Game 的三种思路 - leetcode 55. Jump Game

    Jump Game 是一道有意思的题目.题意很简单,给你一个数组,数组的每个元素表示你能前进的最大步数,最开始时你在第一个元素所在的位置,之后你可以前进,问能不能到达最后一个元素位置. 比如: A = ...

  6. JavaScript 位运算总结&拾遗

    最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...

  7. 文件夹管理工具(MVC+zTree+layer)(附源码)

    写在前 之前写了一篇关于 文件夹与文件的操作的文章  操作文件方法简单总结(File,Directory,StreamReader,StreamWrite )  把常用的对于文件与文件夹的操作总结了一 ...

  8. 项目分享二:APP 小红点中数字的处理

    小红点,是 APP 中最常见的一个功能,我们先来看一下面的案例,下图中,待评价的商品有 2 个,点击“评价晒单”按钮进行评价后,那么待评价数量应该变成 1,那么这个功能是如何去实现的呢? 一般来说,实 ...

  9. C# 如何捕获键盘按钮和组合键以及KeyPress/KeyDown事件之间的区别 (附KeyChar/KeyCode值)

    1. 首先将窗口属性KeyPreview设为true,如果属性对话框中找不到,就直接在代码里添加: 2. 添加KeyPress / KeyDown事件: 1.KeyPress 和KeyDown .Ke ...

  10. Spring学习进阶(四) Spring JDBC

    Spring JDBC是Spring所提供的持久层技术.主要目的是降低使用JDBC API的门槛,以一种更直接,更简洁的方式使用JDBC API.在Spring JDBC里用户仅需要做哪些比不可少的事 ...