可持久化并查集

显然是可持久化并查集裸题吧。。。

就是题面长得有点恶心,被闪指导狂喷。

对于\(K\)操作,直接\(O(1)\)赋值修改。

对于\(R\)操作,并查集上直接连边。

对于\(T\)操作,先询问当前是否连通,若联通再询问\(t\)次操作前是否连通。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 300000
#define LN 20
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n;
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
Tp I void readc(Ty& x) {W(isspace(x=tc()));}
}F;
class PersistentUnionFindSet//可持久化并查集
{
private:
#define LT l,mid,O[rt].S[0]
#define RT mid+1,r,O[rt].S[1]
int n,Nt,Rt[N+5];struct node {int f,g,S[2];}O[N*LN<<1];
I int getfa(CI rt,CI x) {RI t=Qry(x,1,n,rt);return O[t].f^x?getfa(rt,O[t].f):t;}//找祖先
I void Build(CI l,CI r,int& rt)//建树
{
if(rt=++Nt,l==r) return (void)(O[rt].f=l);RI mid=l+r>>1;
Build(LT),Build(RT);
}
I int Qry(CI x,CI l,CI r,CI rt)//询问
{
if(!rt) return 0;if(l==r) return rt;RI mid=l+r>>1;
return x<=mid?Qry(x,LT):Qry(x,RT);
}
I void Upt(CI x,CI f,CI l,CI r,int& rt)//修改父亲
{
if(O[++Nt]=O[rt],rt=Nt,l==r) return (void)(O[rt].f=f);RI mid=l+r>>1;
x<=mid?Upt(x,f,LT):Upt(x,f,RT);
}
I void Add(CI x,CI l,CI r,int& rt)//将深度加1
{
if(O[++Nt]=O[rt],rt=Nt,l==r) return (void)++O[rt].g;RI mid=l+r>>1;
x<=mid?Add(x,LT):Add(x,RT);
}
public:
I void Init(CI _n) {Build(1,n=_n,Rt[0]);}
I bool Identify(CI v,CI x,CI y) {return getfa(Rt[v],x)==getfa(Rt[v],y);}//判断是否连通
I void Union(CI v,CI x,CI y)//按秩合并
{
Rt[v]=Rt[v-1];RI fx=getfa(Rt[v],x),fy=getfa(Rt[v],y);if(fx==fy) return;
O[fx].g<O[fy].g&&swap(fx,fy),Upt(O[fy].f,O[fx].f,1,n,Rt[v]),
O[fx].g==O[fy].g&&(Add(O[fx].f,1,n,Rt[v]),0);
}
}U;
int main()
{
freopen("history.in","r",stdin),freopen("history.out","w",stdout);
RI Qt,x,y,z,k=0,op=0,cnt=0;char t;F.read(n,Qt),U.Init(n);W(Qt--) switch(F.readc(t),t)
{
case 'K':F.read(x),k=x;break;//K操作
case 'R':F.read(x,y),U.Union(++cnt,(x+op*k)%n+1,(y+op*k)%n+1);break;//R操作
case 'T'://T操作
if(F.read(x,y,z),++x,++y,x==y||!U.Identify(cnt,x,y)) {puts("N"),op=1;continue;}
cnt<=z||!U.Identify(cnt-z,x,y)?(puts("Y"),op=0):(puts("N"),op=1);break;
}return 0;
}

【2019.8.20 NOIP模拟赛 T3】小X的图(history)(可持久化并查集)的更多相关文章

  1. 【2019.8.20 NOIP模拟赛 T2】小B的树(tree)(树形DP)

    树形\(DP\) 考虑设\(f_{i,j,k}\)表示在\(i\)的子树内,从\(i\)向下的最长链长度为\(j\),\(i\)子树内直径长度为\(k\)的概率. 然后我们就能发现这个东西直接转移是几 ...

  2. 【2019.7.20 NOIP模拟赛 T1】A(A)(暴搜)

    打表+暴搜 这道题目,显然是需要打表的,不过打表的方式可以有很多. 我是打了两个表,分别表示每个数字所需的火柴棒根数以及从一个数字到另一个数字,除了需要去除或加入的火柴棒外,至少需要几根火柴棒. 然后 ...

  3. 【2019.7.25 NOIP模拟赛 T3】树(tree)(dfs序列上开线段树)

    没有换根操作 考虑如果没有换根操作,我们该怎么做. 我们可以求出原树的\(dfs\)序列,然后开线段树维护. 对于修改操作,我们可以倍增求\(LCA\),然后在线段树上修改子树内的值. 对于询问操作, ...

  4. 【2019.7.26 NOIP模拟赛 T3】化学反应(reaction)(线段树优化建图+Tarjan缩点+拓扑排序)

    题意转化 考虑我们对于每一对激活关系建一条有向边,则对于每一个点,其答案就是其所能到达的点数. 于是,这个问题就被我们搬到了图上,成了一个图论题. 优化建图 考虑我们每次需要将一个区间向一个区间连边. ...

  5. 【2019.7.20 NOIP模拟赛 T2】B(B)(数位DP)

    数位\(DP\) 首先考虑二进制数\(G(i)\)的一些性质: \(G(i)\)不可能有连续两位第\(x\)位和第\(x+1\)位都是\(1\).因为这样就可以进位到第\(x+2\)位.其余情况下,这 ...

  6. 2019.7.26 NOIP 模拟赛

    这次模拟赛真的,,卡常赛. The solution of T1: std是打表,,考场上sb想自己改进匈牙利然后wei了(好像匈牙利是错的. 大力剪枝搜索.代码不放了. 这是什么神仙D1T1,爆蛋T ...

  7. 【NOIP模拟赛】小奇挖矿 2

    [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小奇最初在0 ...

  8. 20161005 NOIP 模拟赛 T3 解题报告

    subset 3.1 题目描述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 1. add s 在集合中加入数字 s. 2. del s 在集合中删除数字 s.保证 s 存在 3. c ...

  9. 神奇的NOIP模拟赛 T3 LGTB 玩THD

    LGTB 玩THD LGTB 最近在玩一个类似DOTA 的游戏名叫THD有一天他在守一座塔,对面的N 个小兵排成一列从近到远站在塔前面每个小兵有一定的血量hi,杀死后有一定的金钱gi每一秒,他都可以攻 ...

随机推荐

  1. Flutter安装入门教程

    ### 前言 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的开发者和 ...

  2. 编译原理之LL(1)文法的判断,递归下降分析程序

    1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...

  3. stream根据条件过滤List<Object>

    List<String> filterUser= new ArrayList<>(); filterUser.add("张三"); List<User ...

  4. MS SQL 设置自增长字段默认值

    dbcc checkident(tablename,reseed,value) 其中tablename为你所要修改的表名,value为默认值.比如你要设置自增长字段值从1开始,则: )

  5. oracle创建新用户并授予权限

    1.同时按下WIN键+R键打开“运行”,输入cmd,回车进入命令提示符 2.输入“sqlplus”后按下回车键,提示输入用户名,输入“sys as sysdba”,按下回车,输入口令,即四-13中设置 ...

  6. Java 正则表达式_网络爬虫

    首先 需要了解 一些 关于 网络爬虫的 基本知识: 网络爬虫: 所谓的 爬虫 就是一个 应用 程序, 这个 应用 程序 会 获取 网络中的 指定信息(网页 数据). 例如百度: 启动 这个 爬虫 程序 ...

  7. Android Fragment 隐藏或显示时调用的生命周期方法

    Fragment使用方式大体分两种: 大家要注意不同的Fragment使用方法,Fragment隐藏和显示调用的生命周期方法是不同的,以下是Fragment显示隐藏调用的方法: //判断是否展示—与V ...

  8. windows下的go get 显示进度

    我的Go版本是:go1.12.7 1.在你的Go安装目录下找到 D:\Go\src\github.com\tools\godep\vendor\golang.org\x\tools\go\vcs\vs ...

  9. Docker 镜像与容器

    镜像和容器的关系   容器提交    commint 作用:       根据容器生成一个新的镜像        命令格式:       docker commit [OPTIONS] CONTAIN ...

  10. 利用 Docker Compose 搭建 SpringBoot 运行环境(超详细步骤和分析)

    0.前言 相信点进来看这篇文章的同学们已经对 Docker Dompose 有一定的了解了,下面,我们拿最简单的例子来介绍如何使用 Docker Compose 来管理项目. 本文例子: 一个应用服务 ...