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. ES6,import时如何正确使用花括号'{ }'

    在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种.前者用于服务器,后者用于浏览器.ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取 ...

  2. 学习Java第一步:安装Intellij IDEA和JDK

    注:其实真正学习一门新语言的第一步并不是安装开发工具,我是C#转JAVA,有一点编程经验了,所以可以直接跳过前面几步,直接上IDE. 1.下载IntelliJ IDEA [官网] http://www ...

  3. 【并发编程】Java中的原子操作

    什么是原子操作 原子操作是指一个或者多个不可再分割的操作.这些操作的执行顺序不能被打乱,这些步骤也不可以被切割而只执行其中的一部分(不可中断性).举个列子: //就是一个原子操作 int i = 1; ...

  4. 力扣(LeetCode)计数质数 个人题解

    统计所有小于非负整数 n 的质数的数量. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 . 一般方法,也就是一般人都会用的,将数从2到它本 ...

  5. Android ConstraintLayout

    对官方例子加上自己的容器即可调整ConstraintLayout实时运行中观察这种布局的变化

  6. Redux第一节

    安装脚手架 npm i -g create-react-app 创建一个Dom create-react-app demo01 安装 Ant Design npm i antd --save 安装re ...

  7. 访问formData的数据

    vant-ui 的 Uploader 上传图片时,用到formData let fd = new FormData(); fd.append('upImgs', file.file); postIma ...

  8. 在SQL Server数据库中执行存储过程很快,在c#中调用很慢的问题

    记录工作中遇到的问题,分享出来: 原博客地址:https://blog.csdn.net/weixin_40782680/article/details/85038281 今天遇到一个比较郁闷的问题, ...

  9. 读取FANUC进给倍率

    读取FANUC机床的倍率信息需要用到 FOCAS链接库. 根据FANUC的连接手册可以知道,进给倍率信号存在 Gn012寄存器中.在机床上更改倍率开关,发现G0012寄存器值变化,经验证G0012就是 ...

  10. 20191010-7 alpha week 1/2 Scrum立会报告+燃尽图 05

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8750 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩 ...