题目描述

某校开展了同学们喜闻乐见的阳光长跑活动。为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动。一时间操场上熙熙攘攘,摩肩接踵,盛况空前。
  为了让同学们更好地监督自己,学校推行了刷卡机制。
  学校中有n个地点,用1到n的整数表示,每个地点设有若干个刷卡机。
  有以下三类事件:
  1、修建了一条连接A地点和B地点的跑道。
  2、A点的刷卡机台数变为了B。
  3、进行了一次长跑。问一个同学从A出发,最后到达B最多可以刷卡多少次。具体的要求如下:
  当同学到达一个地点时,他可以在这里的每一台刷卡机上都刷卡。但每台刷卡机只能刷卡一次,即使多次到达同一地点也不能多次刷卡。
  为了安全起见,每条跑道都需要设定一个方向,这条跑道只能按照这个方向单向通行。最多的刷卡次数即为在任意设定跑道方向,按照任意路径从A地点到B地点能刷卡的最多次数。

题解

我们可以想一下题目说的一条合法路径指的是什么,从一个点到另一个点,中间的路和环都可以走。

所以有一个想法,如果图是静态的,我们可以先边双缩点,然后倍增一下就好了。

但这个图是动态的。所以我们用一个LCT来维护这个过程。

如果我们有一条边连接的两个点原来就是联通的,我们可以把这条链缩成一个点,怎么缩呢,先把链拿出来,然后把这条链上的所有点都指向splay的顶端,然后把顶端的点和其他的点断开,然后这个LCT中只有某些点的father是不对的,所以在访问father的时候要find一下。

注意每次遍历时都要pushdown

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ls tr[x][0]
#define rs tr[x][1]
#define father find(fa[x])
#define N 150009
using namespace std;
int bcj[N],f[N],tr[N][],fa[N],size[N],val[N],n,m,v[N];
bool rev[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
int find(int x){return f[x]=f[x]==x?x:find(f[x]);}
int fd(int x){return bcj[x]=bcj[x]==x?x:fd(bcj[x]);}
inline bool ge(int x){return tr[father][]==x;}
inline bool isroot(int x){return tr[father][]!=x&&tr[father][]!=x;}
inline void pushup(int x){size[x]=size[ls]+size[rs]+val[x];}
inline void pushdown(int x){if(rev[x]){rev[ls]^=;rev[rs]^=;rev[x]^=;swap(ls,rs);}}
inline void _pushdown(int x){if(!isroot(x))_pushdown(father);pushdown(x);}
inline void rotate(int x){
int y=father,o=ge(x);
tr[y][o]=tr[x][o^];fa[tr[y][o]]=y;
if(!isroot(y))tr[find(fa[y])][ge(y)]=x;fa[x]=fa[y];//!!!!
fa[y]=x;tr[x][o^]=y;pushup(y);pushup(x);
}
inline void splay(int x){
_pushdown(x);
while(!isroot(x)){
int y=father;
if(isroot(y))rotate(x);
else rotate(ge(y)==ge(x)?y:x),rotate(x);
}
}
inline void access(int x){for(int y=;x;y=x,x=father)splay(x),tr[x][]=y,pushup(x);}
inline void makeroot(int x){access(x);splay(x);rev[x]^=;}
inline void split(int x,int y){makeroot(x);access(y);splay(y);}
inline void link(int x,int y){makeroot(x);fa[x]=y;}
void dfs(int x,int rt){
f[x]=rt;pushdown(x);////!!!!!!
if(ls)dfs(ls,rt);if(rs)dfs(rs,rt);
}
int main(){
n=rd();m=rd();int opt,x,y;
for(int i=;i<=n;++i)f[i]=i,v[i]=val[i]=rd(),bcj[i]=i;
for(int i=;i<=m;++i){
opt=rd();x=rd();y=rd();
if(opt==){
x=find(x);y=find(y);
if(x==y)continue;
int tx=fd(x),ty=fd(y);
if(tx!=ty){bcj[tx]=ty;link(x,y);}
else{split(x,y);dfs(y,y);val[y]+=size[tr[y][]];tr[y][]=;pushup(y);}
}
else if(opt==){int cha=y-v[x];v[x]=y;x=find(x);access(x);splay(x);val[x]+=cha;pushup(x);}
else{
x=find(x);y=find(y);
if(fd(x)!=fd(y)){printf("-1\n");continue;}
split(x,y);printf("%d\n",size[y]);
}
}
return ;
}

bzoj3959(LCT)的更多相关文章

  1. 一堆LCT板子

    搞了一上午LCT,真是累死了-- 以前总觉得LCT高大上不好学不好打,今天打了几遍感觉还可以嘛= =反正现在的水平应付不太难的LCT题也够用了,就这样好了,接下来专心搞网络流. 话说以前一直YY不出来 ...

  2. 动态树之LCT(link-cut tree)讲解

    动态树是一类要求维护森林的连通性的题的总称,这类问题要求维护某个点到根的某些数据,支持树的切分,合并,以及对子树的某些操作.其中解决这一问题的某些简化版(不包括对子树的操作)的基础数据结构就是LCT( ...

  3. 在此为LCT开一个永久的坑

    其实我连splay都还不怎么会. 今天先抄了黄学长的bzoj2049,以后一定要把它理解了. 写LCT怎么能不%数据结构大神yeweining呢?%%%chrysanthemums  %%%切掉大森林 ...

  4. 【BZOJ2157】旅游 LCT

    模板T,SB的DMoon..其实样例也是中国好样例...一开始不会复制,yangyang:找到“sample input”按住shift,按page down.... #include <ios ...

  5. 【BZOJ3669】[Noi2014]魔法森林 LCT

    终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...

  6. 【BZOJ1180】: [CROATIAN2009]OTOCI & 2843: 极地旅行社 LCT

    竟然卡了我....忘记在push_down先下传父亲的信息了....还有splay里for():卡了我10min,但是双倍经验还是挺爽的,什么都不用改. 感觉做的全是模板题,太水啦,不能这么水了... ...

  7. 【BZOJ3282】Tree LCT

    1A爽,感觉又对指针重怀信心了呢= =,模板题,注意单点修改时splay就好,其实按吾本意是没写的也A了,不过应该加上能更好维护平衡性. ..还是得加上好= = #include <iostre ...

  8. BZOJ2888 资源运输(LCT启发式合并)

    这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式 ...

  9. LCT裸题泛做

    ①洞穴勘测 bzoj2049 题意:由若干个操作,每次加入/删除两点间的一条边,询问某两点是否连通.保证任意时刻图都是一个森林.(两点之间至多只有一条路径) 这就是个link+cut+find roo ...

随机推荐

  1. 爬虫——scrapy框架

    Scrapy是一个异步处理框架,是纯Python实现的爬虫框架,其架构清晰,模块之间的耦合程度低,可拓展性强,可以灵活完成各种需求.我们只需要定制几个模块就可以轻松实现一个爬虫. 1.架构  Scra ...

  2. WCF上传下载文件

    思路:上传时将要上传的文件流提交给服务器端 下载时只需要将服务器上的流返回给客户端即可 1.契约,当需要传递的数量多于一个时就需要通过messagecontract来封装起来 这里分别实现了上传和下载 ...

  3. IdentityServer4【Topic】之登陆注册

    Sign-in 登陆注册 为了让标识服务器(identity server)代表用户发出令牌,该用户必须登录到标识服务器. Cookie authentication Cookie认证 身份验证是由来 ...

  4. C#设计模式之1:策略模式

    首先需要说明的是该系列的所有内容都是基于headfirst设计模式来描述的.因为我之前也看过不少关于设计模式的书,还是发现这本最好,因为这本书里面给出的例子是最贴切实际的.不说了,开始这个系列吧! 策 ...

  5. eclipse下的spring环境配置

    1) 工具: (1) jdk (2) spring.jar  .commons-logging-1.1.1.jar (因为只是做的简单的demo,所以就只用这两个jar包) spring.jar 是包 ...

  6. java中去除字符串(String)中的换行字符(\r \n \t)

    例1: public class Test { public static void main(String[] args) { String s = "'sds gdasda" ...

  7. Guava Cache源码详解

    目录 一.引子 二.使用方法 2.1 CacheBuilder有3种失效重载模式 2.2 测试验证 三.源码剖析 3.1 简介 3.2 源码剖析 四.总结 优点: 缺点: 正文 回到顶部 一.引子 缓 ...

  8. Maven 项目 无缘无故报错:版本冲突,其他机器上正常-提交的时候报冲突怎么也解决不掉

    2018年: maven突然之间报错了,显示版本冲突,但是其他的机器是好的, 使用命令:mvn compile -P dev -e; 看看测试环境有没有问题,还是有问题.而且,刚开始只是报错:erro ...

  9. Missing artifact com.oracle:ojdbc6:jar:11.2.0.3 Maven中不能引入ojdbc解决方法,错误

    今天从服务器检出Maven项目的时候,遇到了一个问题,就是在pom.xml中引入ojdbc的jar包的时候出错了,提示是Missing artifact com.oracle:ojdbc6:jar:1 ...

  10. 【python练习题】程序4

    # 题目:输入某年某月某日,判断这一天是这一年的第几天? import time year = input('输入年份: \n') month = input('输入月份: \n') day = in ...