Max Mex

题目地址:https://codeforces.com/contest/1084/problem/F

然后合并时注意分情况讨论:


参考代码:
 #include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mkp make_pair
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
const int maxn=2e5+;
int n,q,typ,x,y,cnt,ans;
int a[maxn],in[maxn],out[maxn];
int dep[maxn],fc[],fa[][maxn];
vector<int> G[maxn];
PII res; inline void dfs(int u)
{
in[u]=++cnt;
for(int i=;fc[i]<=dep[u];++i) fa[i][u]=fa[i-][fa[i-][u]];
for(int i=,len=G[u].size();i<len;++i)
{
dep[G[u][i]]=dep[u]+;fa[][G[u][i]]=u;
dfs(G[u][i]);
}
out[u]=++cnt;
} inline int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=,t=dep[x]-dep[y];t;++i)
if(t&fc[i]) x=fa[i][x],t^=fc[i];
for(int i=;~i;--i) if(fa[i][x]^fa[i][y])
x=fa[i][x],y=fa[i][y];
return x==y? x:fa[][x];
} namespace Segment
{
#define ls (rt<<1)
#define rs (rt<<1|1)
PII T[maxn<<]; bool anc(int x,int y){return in[x]<=in[y]&&out[x]>=out[y];} PII check(PII x,int y)
{
if(!x.fi || !y) return mkp(,);
if(anc(x.fi,x.se)) swap(x.fi,x.se);
if(anc(x.se,x.fi))
{
if(anc(x.fi,y)) return mkp(y,x.se);
if(anc(x.se,y))
{
if(anc(y,x.fi)) return x;
if(LCA(x.fi,y)==x.se) return mkp(x.fi,y);
return mkp(,);
}
return mkp(y,x.fi);
} if(anc(x.fi,y)) return mkp(y,x.se);
if(anc(x.se,y)) return mkp(x.fi,y);
if(!anc(LCA(x.fi,x.se),y)) return mkp(,);
if(!anc(y,x.fi) && !anc(y,x.se)) return mkp(,);
return x;
} PII merge(PII x,PII y)
{
if(x.fi==-) return y;
x=check(x,y.fi);x=check(x,y.se);
return x;
} void update(int rt,int l,int r,int pos,int x)
{
if(l==r){T[rt]=mkp(x,x);return ;}
int mid=l+r>>;
if(pos<=mid) update(ls,l,mid,pos,x);
else update(rs,mid+,r,pos,x);
T[rt]=merge(T[ls],T[rs]);
} bool query(int rt,int l,int r)
{
PII tmp=merge(res,T[rt]);
if(tmp.fi){res=tmp;ans=r;return true;}
if(l==r) return false;//
int mid=l+r>>;
if(query(ls,l,mid)) query(rs,mid+,r);
return false;
}
}
using namespace Segment; int main()
{
n=read(); fc[]=;
for(int i=;i<=n;++i) a[i]=read()+;
for(int i=;i<=n;++i) G[read()].pb(i);
for(int i=;i<=;++i) fc[i]=fc[i-]<<;
dfs();
for(int i=;i<=n;++i) update(,,n,a[i],i);
q=read();
while(q--)
{
typ=read();
if(typ==)
{
x=read();y=read();swap(a[x],a[y]);
update(,,n,a[x],x);update(,,n,a[y],y);
}
else
{
res=mkp(-,);ans=;query(,,n);
printf("%d\n",ans);
}
} return ;
}

;

CF 526F Max Mex(倍增求LCA+线段树路径合并)的更多相关文章

  1. [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)

    [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...

  2. CF 519E(树上倍增求lca)

    传送门:A and B and Lecture Rooms 题意:给定一棵树,每次询问到达点u,v距离相等的点有多少个. 分析:按情况考虑: 1.abs(deep[u]-deep[v])%2==1时, ...

  3. 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)

    洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...

  4. 倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))

    倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...

  5. [学习笔记] 树上倍增求LCA

    倍增这种东西,听起来挺高级,其实功能还没有线段树强大.线段树支持修改.查询,而倍增却不能支持修改,但是代码比线段树简单得多,而且当倍增这种思想被应用到树上时,它的价值就跟坐火箭一样,噌噌噌地往上涨. ...

  6. 树上倍增求LCA(最近公共祖先)

    前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...

  7. [算法]树上倍增求LCA

    LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...

  8. 【倍增】洛谷P3379 倍增求LCA

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  9. hdu 2586 How far away ? 倍增求LCA

    倍增求LCA LCA函数返回(u,v)两点的最近公共祖先 #include <bits/stdc++.h> using namespace std; *; struct node { in ...

随机推荐

  1. 轻松实现C/C++各种常见进制相互转换

    其它进制转为十进制 在实现这个需求之前,先简单介绍一个c标准库中的一个函数: long strtol( const char *str, char **str_end, int base); 参数详细 ...

  2. lqb 基础练习 闰年判断

    基础练习 闰年判断 时间限制:1.0s   内存限制:256.0MB     问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 1. 年份是4的倍数而不是100的倍 ...

  3. (二十九)golang--map

    map:是key-value数据结构,又称为字段或者关联数组,类似其它编程语言的集合: 基本语法:var 名称 map[键类型]值类型 key的类型可以是:bool.数字.string.指针.管道,还 ...

  4. docker入门篇

    在网上的教程中,大多数是建议利用linux来安装docker,在此我也建议大家用linux安装,为什么?请看下图 docker使用go语言开发,并且运行在linux系统下,而如果想用window运行, ...

  5. RocketMQ一个新的消费组初次启动时从何处开始消费呢?

    目录 1.抛出问题 1.1 环境准备 1.2 消息发送者代码 1.3 消费端验证代码 2.探究CONSUME_FROM_MAX_OFFSET实现原理 2.1 CONSUME_FROM_LAST_OFF ...

  6. python3 之 文件read方法(read、readline、readlines)

    目录 一.read方法 二.readline方法 三.readlines方法 正文 python3中,读取文件有三种方法:read().readline().readlines(). 此三种方法,均支 ...

  7. kafka-manager新手安装入门指南

    Kafka-manager安装教程 使用环境 ubuntu18.04 Java 8 一.下载kafka 官网下载地址如下 https://www.apache.org/dyn/closer.cgi?p ...

  8. 像黑客一样写博客–Pelican快速搭建静态博客

    "像黑客一样写博客",通过文本编辑器(Markdown编辑器)即可实现写博客,而且是静态的,很神奇吧,这里的方案是Pelican. 为啥叫 Pelican 这么奇怪的名字 &quo ...

  9. 2019-11-19:xxe漏洞利用,笔记

    xxe,也就是xml,外部实体注入攻击,漏洞是对非安全的外部实体数据进行处理时引发的安全问题,要了解xxe,就必须懂得xml的一些规则xml是用于标记电子文件使其具有结构性的标记语言,可以用来标记数据 ...

  10. 记一次将本地工程上传到github的过程

    记一次将本地工程上传到github的过程 1.首先,进入本地工程所在文件夹,运行git init将工程初始化为git仓库: XH@DESKTOP-82MT9LU MINGW64 ~/Desktop/t ...