lct+并查集

联赛之后忘了很多东西 复习一下

这并不是一棵树,所以我们不能直接上lct

但是把双联通分量缩了以后就是一棵树了

怎么缩呢 就是把splay拆了合并到一个点上

连通性和双联通分量拿两个并查集维护

access的时候x=find(fa[x])

#include<bits/stdc++.h>
using namespace std;
const int N = 1.5e5 + ;
struct ufs {
int fa[N];
ufs() { for(int i = ; i < N; ++i) fa[i] = i; }
int find(int x)
{
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void link(int u, int v)
{
fa[find(u)] = find(v);
}
bool con(int u, int v)
{
return find(u) == find(v);
}
} a, b;
int n, m;
int val[N];
queue<int> q;
namespace lct
{
struct node {
int rev, sum, w, f;
int ch[];
} t[N];
bool isr(int x) { return !t[x].f || (x != t[t[x].f].ch[] && x != t[t[x].f].ch[]); }
int wh(int x) { return x == t[t[x].f].ch[]; }
void paint(int x)
{
t[x].rev ^= ;
swap(t[x].ch[], t[x].ch[]);
}
void upd(int x)
{
t[x].sum = t[t[x].ch[]].sum + t[t[x].ch[]].sum + t[x].w;
}
void pd(int x)
{
if(!t[x].rev) return;
paint(t[x].ch[]);
paint(t[x].ch[]);
t[x].rev ^= ;
}
void rotate(int x)
{
int y = t[x].f, z = t[y].f, w = wh(x);
if(!isr(y)) t[z].ch[wh(y)] = x;
t[x].f = z;
t[y].ch[w] = t[x].ch[w ^ ];
t[t[x].ch[w ^ ]].f = y;
t[x].ch[w ^ ] = y;
t[y].f = x;
upd(y);
upd(x);
}
void ptd(int x)
{
if(!isr(x)) ptd(t[x].f);
pd(x);
}
void splay(int x)
{
ptd(x);
for(; !isr(x); rotate(x))
if(!isr(t[x].f)) rotate(wh(x) == wh(t[x].f) ? t[x].f : x);
}
void access(int x)
{
for(int p = ; x; p = x, x = b.find(t[x].f))
{
splay(x);
t[x].ch[] = p;
t[p].f = x;
upd(x);
}
}
void rever(int x)
{
access(x);
splay(x);
paint(x);
}
void expose(int x, int y)
{
rever(y);
access(x);
splay(x);
}
void link(int u, int v)
{
rever(u);
t[u].f = v;
}
void rebuild(int x, int y)
{
int rt = x;
q.push(x);
expose(x, y);
while(!q.empty())
{
x = q.front();
b.link(x, rt);
q.pop();
if(t[x].ch[]) q.push(t[x].ch[]);
if(t[x].ch[]) q.push(t[x].ch[]);
t[x].ch[] = t[x].ch[] = ;
}
t[rt].w = t[rt].sum;
}
}
void link(int u, int v)
{
u = b.find(u);
v = b.find(v);
if(u == v) return;
if(!a.con(u, v)) lct::link(u, v), a.link(u, v);
else lct::rebuild(u, v);
}
int query(int u, int v)
{
u = b.find(u);
v = b.find(v);
if(!a.con(u, v)) return -;
if(u == v) return lct::t[u].w;
lct::expose(u, v);
return lct::t[u].sum;
}
void add(int x, int v)
{
x = b.find(x);
lct::t[x].w += v;
lct::t[x].sum += v;
lct::splay(x);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i) scanf("%d", &lct::t[i].w), val[i] = lct::t[i].sum = lct::t[i].w;
while(m--)
{
int opt, u, v;
scanf("%d%d%d", &opt, &u, &v);
if(opt == ) link(u, v);
if(opt == ) add(u, v - val[u]), val[u] = v;
if(opt == ) printf("%d\n", query(u, v));
}
return ;
}

bzoj2959的更多相关文章

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

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

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

    [BZOJ2959]长跑(Link-Cut Tree,并查集) 题面 BZOJ 题解 如果保证不出现环的话 妥妥的\(LCT\)傻逼题 现在可能会出现环 环有什么影响? 那就可以沿着环把所有点全部走一 ...

  3. bzoj2959: 长跑

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  4. 【BZOJ2959】长跑 (LCT+并查集)

    Time Limit: 1000 ms   Memory Limit: 256 MB Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室 ...

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

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

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

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

  7. 【bzoj2959】长跑 LCT+并查集

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

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

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

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

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

随机推荐

  1. hdu1034 简单模拟

    这里开一个二维数组.num[105][2];   我也不知道N有多少,随便开的,  那么这里num[i][0] 表示当前 第 i 个人拥有的糖果数,num[i][1]表示他上面一个人分给他的糖果数.详 ...

  2. Triangle 三角形——找出三角形中从上至下和最小的路

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  3. linux与python

    linux一般都装有python,但是版本不一定,需要自己查看,如果版本过低,需要重装.查看python版本方法,直接在命令行输入 python,此时会进入python命令行,同时会显示python版 ...

  4. Android的logger机制分析

    分析安卓的Logger机制 一.概述 Logger机制是在Android系统中提供的一个轻量级的日志系统,这个日志系统是以驱动程序的形式在内核空间实现的,在用户空间分别提供了Java接口和C/C++接 ...

  5. 运维基础-Linux发展史、安装、基本操作

    Linux是目前互联网运维.大数据.云计算方向首选操作系统平台,能够在物理服务器Dell.hp.等server,以及当前主流的云平台,阿里云,腾讯云上面部署 发展史 . . .略过..... 物理服务 ...

  6. kubernetes容器探针检测

    系列目录 kubernetes提供了livenessProbe(可用性探针)和readinessProbe(就绪性探针)对容器的健康性进行检测,当然这仅仅简单的关于可用性方面的探测,实际上我们不仅仅要 ...

  7. celery模块

    Celery Celery是管理分布式任务队列的工具,其本身并不是任务队列. Celery常见概念有brokers.backend.workers.tasks. brokers:中间人,是Celery ...

  8. (转)Java web 项目中文件路径

    文件路径分为绝对路径和相对路径,在项目中页面跳转.配置文件读写.文件上传下载等等许多地方都涉及到文件路径问题. 一篇好文转载于此:http://blog.csdn.net/shendl/archive ...

  9. Linux 系统编程中环境变量的使用

    前言 在 UNIX Like 系统中,存有各类系统/应用程序的环境变量,可通过修改之改变系统/应用程序的执行效果:除此之外,用户还可以定义自己的环境变量,供自己写的程序使用.本文将说明如何在程序中设置 ...

  10. struts2的输入检验

    一.输入校验简介 一个健壮的Web应用程序必须确保用户输入是合法的.比如在注册用户的时候,将用处注册信息保存到数据库之前一般我们会判断用户输入的密码长度是否过短,或者用户的email地址格式是否正确. ...