【BZOJ2959】长跑(Link-Cut Tree,并查集)

题面

BZOJ

题解

如果保证不出现环的话

妥妥的\(LCT\)傻逼题

现在可能会出现环

环有什么影响?

那就可以沿着环把所有点全部走一遍吧

所以,相当于把环看成一个点来搞一搞

所以,维护一个并查集

记录一下每个点被缩成了哪个点

然后再用\(LCT\)维护缩点后的树就行啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 320000
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Node
{
int ch[2],ff;
int sum,rev,v;
}t[MAX<<1];
int S[MAX<<1],top;
int tot,n,m,a[MAX<<1];
int f[MAX<<1];
int ff[MAX<<1];
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int Getf(int x){return x==ff[x]?x:ff[x]=Getf(ff[x]);}
bool isroot(int x){return t[getf(t[x].ff)].ch[0]!=x&&t[getf(t[x].ff)].ch[1]!=x;}
void pushup(int x){t[x].sum=t[lson].sum+t[rson].sum+t[x].v;}
void pushdown(int x)
{
if(!t[x].rev)return;
swap(lson,rson);
t[lson].rev^=1;t[rson].rev^=1;
t[x].rev^=1;
}
void rotate(int x)
{
int y=getf(t[x].ff),z=getf(t[y].ff);
int k=t[y].ch[1]==x;
if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);pushup(x);
}
void Splay(int x)
{
S[top=1]=x=getf(x);
for(int i=x;!isroot(i);i=getf(t[i].ff))S[++top]=getf(t[i].ff);
while(top)pushdown(S[top--]);
while(!isroot(x))
{
int y=getf(t[x].ff),z=getf(t[y].ff);
if(!isroot(y))
(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x){x=getf(x);for(int y=0;x;y=x,x=getf(t[x].ff))Splay(x),t[x].ch[1]=y,pushup(x);}
void makeroot(int x){x=getf(x);access(x);Splay(x);t[x].rev^=1;}
void split(int x,int y){x=getf(x);y=getf(y);makeroot(x);access(y);Splay(y);}
void link(int x,int y){x=getf(x);y=getf(y);makeroot(x);t[x].ff=y;pushup(y);}
int findroot(int x){getf(x);access(x);Splay(x);while(lson)x=lson;return x;}
void dfs(int x)
{
f[getf(x)]=tot;
t[tot].v+=t[x].v;
t[tot].sum+=t[x].v;
if(lson)dfs(lson);
if(rson)dfs(rson);
}
void Link(int x,int y)
{
if(Getf(x)!=Getf(y))ff[Getf(x)]=Getf(y),link(getf(x),getf(y));
else
{
x=getf(x);y=getf(y);
++tot;ff[tot]=f[tot]=tot;
split(x,y);
dfs(y);
}
}
void Modify(int u,int v)
{
makeroot(getf(u));
t[getf(u)].v-=a[u];a[u]=v;
t[getf(u)].v+=a[u];
pushup(getf(u));
}
int Query(int u,int v)
{
if(Getf(u)!=Getf(v))return -1;
u=getf(u);v=getf(v);
split(u,v);
return t[v].sum;
}
int main()
{
tot=n=read();m=read();
for(int i=1;i<=n;++i)f[i]=ff[i]=i,t[i].v=a[i]=read();
int opt,u,v;
while(m--)
{
opt=read();u=read();v=read();
if(opt==1)Link(u,v);
else if(opt==2)Modify(u,v);
else printf("%d\n",Query(u,v));
}
return 0;
}

【BZOJ2959】长跑(Link-Cut Tree,并查集)的更多相关文章

  1. Link Cut Tree 总结

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

  2. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  3. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  4. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  5. (RE) luogu P3690 【模板】Link Cut Tree

    二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...

  6. Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题

    A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...

  7. Link/cut Tree

    Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...

  8. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  9. bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

    link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...

  10. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

随机推荐

  1. Mac通过brew安装reds、memcached

    redis brew install php70-redis 配置文件: /usr/local/etc/php/7.0/conf.d/ext-redis.ini memcached brew inst ...

  2. ★Linux桌面系统技巧(作为客户端)

    [安装chrome浏览器]* 下载(已下载完成):32位:wget https://dl.google.com/linux/direct/google-chrome-stable_current_i3 ...

  3. (转)CocoaPods:管理Objective-c 程序中各种第三方开源库关联

    在我们的iOS程序中,经常会用到多个第三方的开源库,通常做法是去下载最新版本的开源库,然后拖拽到工程中. 但是,第三方开源库的数量一旦比较多,版本的管理就非常的麻烦.有没有什么办法可以简化对第三方库的 ...

  4. centos/linux下的安装Nginx

    1.安装gcc编译器 先查看gcc编译器是否安装 在shell控制台输入gcc-v 如果没有安装请看下一步 使用yuma安装gcc yum intsall gcc 看到如下视图则说明安装成功 2.安装 ...

  5. JavaScript实现排序二叉树的相关算法

    1.创建排序二叉树的构造函数 /** * 创建排序二叉树的构造函数 * @param valArr 排序二叉树中节点的值 * @constructor */ function BinaryTree(v ...

  6. Java版2048

    功能要求:2048的基本界面,能够实现2048的游戏功能. 总思路:两个类:Game和GameListener. Game负责界面的实现和paint方法的重写 GameListener负责实现键盘和鼠 ...

  7. Effective Java 第三版——34. 使用枚举类型替代整型常量

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Eclipse远程调试hadoop源码

    1. 修改对应调试端口 之前的一篇blog里讲述了hadoop单机版调试的方法,那种调试只限于单机运行hadoop命令而已,对于运行整个hadoop环境而言是不可取的,因为hadoop会开启多个jav ...

  9. IS-IS 路由协议 总结

    第一章 is-is的协议概述 1. 发展史 Is-is最早是iso为osi模型中CLNP而设计的协议,后来根据发展需要,也支持了TCP/IP协议,因此,is-is叫做integrated is-is或 ...

  10. jmeter压力测试笔记- HTTP协议

    一.目标 使用jmeter进行HTTP接口压力测试: 命令行方式运行,方便在linux环境运行: 二.面临的问题 支持多环境测试(开发.测试.生产环境) 支持用户数据.线程数.循环次数等配置在运行时自 ...