bzoj 2959: 长跑【LCT+并查集】
如果没有环的话直接LCT
考虑有环怎么办,如果是静态的话就tarjan了,但是这里要动态的缩环
具体是link操作的时候看一下是否成环(两点已联通),成环的话就用并查集把这条链缩到一个点,把权值加给祖先,断开所有splay上儿子。不过父亲这里不用管,就先让他们连着
每次操作的时候都用并查集找到支配点再进行操作
access跳父亲的时候直接跳到父亲的支配点
然后splay的时候,前面用栈倒着pushdown的时候,把所有父亲指向都改到他的支配点上,这样就相当于操作这个splay的时候只有支配点了,被支配点全都断掉了
判断联通那里,因为没有cut,所以直接用另一个并查集维护连通性比较方便
#include<iostream>
#include<cstdio>
using namespace std;
const int N=300005;
int n,m,f[N],fa[N],a[N],s[N],top;
struct lct
{
int f,c[2],s,v,lz;
}t[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int zhao(int x)
{
return (f[x]==x)?x:f[x]=zhao(f[x]);
}
int zhaof(int x)
{
return (fa[x]==x)?x:fa[x]=zhaof(fa[x]);
}
void ud(int x)
{
t[x].s=t[t[x].c[0]].s+t[t[x].c[1]].s+t[x].v;
}
void pd(int x)
{
if(t[x].lz)
{
swap(t[x].c[0],t[x].c[1]);
t[t[x].c[0]].lz^=1;
t[t[x].c[1]].lz^=1;
t[x].lz=0;
}
}
bool srt(int x)
{
int fx=t[x].f;
return t[fx].c[0]!=x&&t[fx].c[1]!=x;
}
void zhuan(int x)
{
int y=t[x].f,z=t[y].f,l=(t[y].c[1]==x),r=l^1;
if(!srt(y))
t[z].c[t[z].c[1]==y]=x;
t[x].f=z;
t[y].c[l]=t[x].c[r];
t[t[y].c[l]].f=y;
t[x].c[r]=y;
t[y].f=x;
ud(y);
ud(x);
}
void splay(int x)
{
s[top=1]=x;
for(int i=x;!srt(i);i=zhao(t[i].f))
s[++top]=zhao(t[i].f);
while(top)
pd(s[top]),t[s[top]].f=zhao(t[s[top]].f),top--;
while(!srt(x))
{
int y=t[x].f,z=t[y].f;
if(!srt(y))
{
if((t[y].c[1]==x)^(t[z].c[1]==y))
zhuan(x);
else
zhuan(y);
}
zhuan(x);
}
}
void acc(int x)
{
for(int i=0;x;i=x,x=zhao(t[x].f))
{//cerr<<x<<" "<<i<<endl;
splay(x);//cerr<<"OK"<<endl;
t[x].c[1]=i;
ud(x);
}
}
void mkrt(int x)
{
acc(x);
splay(x);
t[x].lz^=1;
}
void lk(int x,int y)
{
mkrt(x);
t[x].f=y;
}
void hb(int x,int fat)
{
if(!x)
return;
f[zhao(x)]=fat;
pd(x);
if(x!=fat)
t[fat].v+=t[x].v;
hb(t[x].c[0],fat);
hb(t[x].c[1],fat);
t[x].c[0]=t[x].c[1]=0;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
t[i].v=a[i]=read(),f[i]=fa[i]=i;
while(m--)
{
int o=read(),x=read(),y=read();//cerr<<o<<endl;
if(o==1)
{
int fx=zhao(x),fy=zhao(y);
if(fx==fy)
continue;
int r1=zhaof(fx),r2=zhaof(fy);
if(r1==r2)
{
mkrt(fx);
acc(fy);
splay(fy);
hb(fy,fy);
ud(fy);
}
else
{//cerr<<fx<<" "<<fy<<endl;
fa[r2]=r1;
lk(fx,fy);
}
}
else if(o==2)
{
int fx=zhao(x);
acc(fx);
splay(fx);
t[fx].v=t[fx].v-a[x]+y;
a[x]=y;
ud(fx);
}
else
{
int fx=zhao(x),fy=zhao(y);//cerr<<fx<<" "<<fy<<endl;
if(zhaof(fx)!=zhaof(fy))
puts("-1");
else
{//cerr<<fx<<" "<<fy<<endl;
mkrt(fx);//cerr<<"OK"<<endl;
acc(fy);
splay(fy);
printf("%d\n",t[fy].s);
}
}
}
return 0;
}
bzoj 2959: 长跑【LCT+并查集】的更多相关文章
- BZOJ 2959 长跑 (LCT+并查集)
题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...
- BZOJ 2959: 长跑 LCT_并查集_点双
真tm恶心...... Code: #include<bits/stdc++.h> #define maxn 1000000 using namespace std; void setIO ...
- 【bzoj2959】长跑 LCT+并查集
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...
- BZOJ 2959 长跑 (LCT、并查集)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2959 题解 真是被这题搞得心态大崩--调了7个小时--然而并查集都能写成\(O(n^2) ...
- BZOJ 2959: 长跑 lct 双联通分量 并查集 splay
http://www.lydsy.com/JudgeOnline/problem.php?id=2959 用两个并查集维护双联通分量的编号和合并. #include<iostream> # ...
- BZOJ 2959: 长跑 [lct 双连通分量 并查集]
2959: 长跑 题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树 不是树
- BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...
- bzoj2959: 长跑 LCT+并查集+边双联通
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2959 题解 调了半天,终于调完了. 显然题目要求是求出目前从 \(A\) 到 \(B\) 的可 ...
- bzoj2959: 长跑(LCT+并查集)
题解 动态树Link-cut tree(LCT)总结 LCT常数大得真实 没有环,就是\(lct\)裸题吧 有环,我们就可以绕环转一圈,缩点 怎么搞? 当形成环时,把所有点的值全部加到一个点上,用并查 ...
- 【bzoj4998】星球联盟 LCT+并查集
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
随机推荐
- 高速清除winXP系统中explorer.exe病毒
关于这个explorer.exe病毒.是眼下xp最为常见的一个病毒,会大量的消耗系统资源,造成电脑特别的卡顿. 1.关闭还原(假设没有,则跳过),为的是防止我们改动后,还原之后又回来了. 2.打开注冊 ...
- SQL SELECT TOP, LIMIT, ROWNUM 子句
SQL SELECT TOP, LIMIT, ROWNUM 子句 SQL SELECT TOP 子句 SELECT TOP 子句用于规定要返回的记录的数目. SELECT TOP 子句对于拥有数千条记 ...
- NAND FLash基础概念介绍
一.引脚介绍 引脚名称 引脚功能 CLE 命令锁存功能 ALE 地址锁存功能 /CE 芯片使能 /RE 读使能 /WE 写使能 /WP 写保护 R/B 就绪/忙输出信号 Vcc 电源 Vss 地 N. ...
- zedboard中OLED源码
#include <stdio.h> #include "platform.h" #include "xil_types.h" #include & ...
- java开始到熟悉100-102
本次内容:arraylist() 1. package list; import java.util.ArrayList; import java.util.Date; import java.uti ...
- scala快速学习笔记(二):控制结构,类和对象
IV.控制结构 1.if/else 除基本用法外,if/else语句能用来赋值,进而代替?:运算符.这得益于在Scala中,每个语句块都有值,就是该语句块最后一个语句的值.请看下面的代码. def a ...
- angularjs开发常见问题-2(angularjs内置过滤器)
在angular中内置了几个经常使用的filter,能够简化我们的操作. 过滤器使用 '|' 符号,概念有点相似于linux中的管道. 1.filter (过滤) filter能够依据条件过滤数据.样 ...
- 1507: [NOI2003]Editor
1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MB Submit: 3535 Solved: 1435 [Submit][St ...
- java里类方法和实例方法
实例方法相对于静态方法(或者叫类方法)而言没有 static 前缀类般方法被对象拥有(也称之实例方法原因)特点定义时候前面没有 static 前缀本类直接调用时候必须也实例方法内否则调用前必须先实例出 ...
- 使用delphi 开发多层应用(十六)使用XMLRPC 实现basic4android 远程调用RTC服务(讲述了RTC的特点,其底层通讯协议是自己封装SOCK 库,与kbmmw 的适合场合不完全一样)
RealThinClient (以下简称RTC) 也是一款delphi 多层开发的框架,由于其底层通讯协议是自己封装SOCK 库,抛弃了 大家诟病的indy,因此表现的非常稳定,效率也非常高, ...