【BZOJ2959】长跑(Link-Cut Tree,并查集)
【BZOJ2959】长跑(Link-Cut Tree,并查集)
题面
题解
如果保证不出现环的话
妥妥的\(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,并查集)的更多相关文章
- Link Cut Tree 总结
Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...
- link cut tree 入门
鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- Link Cut Tree学习笔记
从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...
- (RE) luogu P3690 【模板】Link Cut Tree
二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...
- Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题
A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...
- Link/cut Tree
Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...
- 洛谷P3690 Link Cut Tree (模板)
Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...
- bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门
link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
随机推荐
- HttpGet HttpPost
public string HttpGet(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)Web ...
- Phalcon调试大杀器之phalcon-debugbar安装
Phalcon 是一款非常火的高性能C扩展php开发框架.特点是高性能低耦合,但遗憾的是长期缺少一款得力的调试辅助工具. 目前版本主要以Laravel debugbar的具有功能为蓝本开发,并针对ph ...
- 阿里巴巴Java开发规约插件地址
Git地址: https://github.com/alibaba/p3c eclipse 安装地址: https://p3c.alibaba.com/plugin/eclipse/update
- 一致性哈希(附带C++实现)
在分布式集群中,对机器的添加删除,或者机器故障后自动脱离集群这些操作是分布式集群管理最基本的功能.如果采用常用的hash(object)%N算 法,那么在有机器添加或者删除后,就需要大范围的移动原有数 ...
- go 开发环境安装教程 windows
首先进入go 语言官网下载最新安装包,我目前安装的版本是 1.8.3版本:go1.8.3.windows-amd64.msi 如果下载慢,这个是百度云地址:https://pan.baidu ...
- CSS布局(一) 盒子模型
一.盒子模型 标准盒子模型 从下图可以看到标准 w3c 盒子模型的范围包括 content.padding.border.margin,并且 content 部分不包含其他部分. 怪异盒子模型 从下图 ...
- vue.js 安装过程(转载)
一.简介 Vue.js 是什么 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核 ...
- MySql全国省市区SQL语句
CREATE TABLE IF NOT EXISTS `province` ( `id` int(11) NOT NULL auto_increment, `provinceID` int(1 ...
- C++学习笔记第三天:类、虚函数、双冒号
类 class Box { public: double length; // 盒子的长度 double breadth; // 盒子的宽度 double height; // 盒子的高度 }; 类成 ...
- Android虚拟机安装
由于虫师那边的源估计到期了,我又找了一波. 打开SDK Manager.exe, 就在安卓目录下. 点击Tools--Options进入配置页面 mirrors.neusoft.edu.cn 配置如下 ...