题解:

树上+可修改莫队

莫队的每一块

可以用一个栈

每一次dfs个数>sqrt(n)(自己选的)的时候就可以跳出了

然后不要忘记分出来最后一块

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=;
int k=,fi[N],unit,Be[N],m,st[N],top,fa[N][],deep[N],n,Q;
int a[N],t[N],op,x,y,p,tim,u=,v=,T,ans[N],vis[N],ne[N],zz[N];
struct Change
{
int u,New,Old;
}cq[N];
struct Query
{
int u,v,tim,id;
int operator <(const Query &a) const
{
if (Be[u]!=Be[a.u])return Be[u]<Be[a.u];
if (Be[v]!=Be[a.v])return Be[v]<Be[a.v];
return tim<a.tim;
}
}q[N];
struct Datalook
{
struct _bol{int l,r;}b[];
int n,Be[N],m,unit,num[N],sum[];
void init()
{
unit=sqrt(n);
m=(n-)/unit+;
for (int i=;i<=n;i++)Be[i]=(i-)/unit+;
for (int i=;i<=m;i++)b[i].l=(i-)*unit+,b[i].r=i*unit;
b[m].r=n;
}
void Add(int v)
{
if (v<=n)sum[Be[v]]+=(++num[v])==;
}
void Del(int v)
{
if (v<=n)sum[Be[v]]-=(--num[v])==;
}
int mex()
{
for (int i=;i<=m;i++)
if (sum[i]!=b[i].r-b[i].l+)
for (int j=b[i].l;j<=b[i].r;j++)
if (!num[j])return j;
return -;
}
}Data;
void jb(int u,int v)
{
ne[k]=fi[u];
zz[k]=v;
fi[u]=k++;
}
void dfs(int u)
{
for (int i=;i<=;i++)
if ((<<i)>deep[u])break;
else fa[u][i]=fa[fa[u][i-]][i-];
int bottom=top;
for (int i=fi[u];i;i=ne[i])
{
int v=zz[i];
if (v!=fa[u][])
{
fa[v][]=u;
deep[v]=deep[u]+;
dfs(v);
if (top-bottom>=unit)
{
m++;
while (top!=bottom)Be[st[top--]]=m;
}
}
}
st[++top]=u;
}
int Lca(int x,int y)
{
if (deep[x]<deep[y])swap(x,y);
int Dis=deep[x]-deep[y];
for (int i=;i<=;i++)
if ((<<i)&Dis)x=fa[x][i];
if (x==y)return x;
for (int i=;i>=;i--)
if (fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return x==y?x:fa[x][];
}
void revise(int u,int d)
{
if (vis[u])
{
Data.Del(a[u]);
Data.Add(d);
}
a[u]=d;
}
void run(int u)
{
if (vis[u])
{
Data.Del(a[u]);
vis[u]=;
}
else
{
Data.Add(a[u]);
vis[u]=;
}
}
void move(int x,int y)
{
if (deep[x]<deep[y])swap(x,y);
while (deep[x]>deep[y])run(x),x=fa[x][];
while (x!=y)run(x),run(y),x=fa[x][],y=fa[y][];
}
int main()
{
scanf("%d%d",&n,&Q);
for (int i=;i<=n;i++)
{
scanf("%d",&a[i]);
t[i]=++a[i];
}
for (int i=;i<=n;i++)
{
scanf("%d%d",&x,&y);
jb(x,y);jb(y,x);
}
dfs();
while (top)Be[st[top--]]=m;
for (int i=;i<=Q;i++)
{
scanf("%d%d%d",&op,&x,&y);
if (op)q[++p]=(Query){x,y,tim,p};
if (!op)cq[++tim]=(Change){x,y+,t[x]},t[x]=y+;
}
Data.n=n+;
Data.init();
sort(q+,q++p);
for (int i=;i<=p;i++)
{
while (T<q[i].tim)T++,revise(cq[T].u,cq[T].New);
while (T>q[i].tim)revise(cq[T].u,cq[T].Old),T--;
if(u!=q[i].u)move(u,q[i].u),u=q[i].u;
if(v!=q[i].v)move(v,q[i].v),v=q[i].v;
int anc=Lca(u,v);
run(anc);
ans[q[i].id]=Data.mex()-;
run(anc);
}
for (int i=;i<=p;i++)printf("%d\n",ans[i]);
}

bzoj4129的更多相关文章

  1. [BZOJ4129]Haruna’s Breakfast(树上带修改莫队)

    BZOJ3585,BZOJ2120,BZOJ3757三合一. 对于树上路径问题,树链剖分难以处理的时候,就用树上带修改莫队. 这里的MEX问题,使用BZOJ3585的分块方法,平衡了时间复杂度. 剩下 ...

  2. 【BZOJ4129】Haruna’s Breakfast(树上莫队)

    [BZOJ4129]Haruna's Breakfast(树上莫队) 题面 BZOJ Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了 ...

  3. 【树上莫队】【带修莫队】【权值分块】bzoj4129 Haruna’s Breakfast

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...

  4. BZOJ4129: Haruna’s Breakfast

    Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵 树上,每个结点都有一样食材,Shimakaze要考验一下她. 每个食材都有一个美 ...

  5. bzoj4129 Haruna’s Breakfast 莫队

    这个思想不难理解了前面几个就能懂 但是代码比较复杂,大概会和之前几次碰到难题的时候一样,一步步思考下去,然后把难点分成好几个板块讲下qwq 首先读入这颗树,预处理下lca,然后就分块,这个时候就会碰到 ...

  6. 【bzoj4129】Haruna’s Breakfast 带修改树上莫队+分块

    题目描述 给出一棵树,点有点权.支持两种操作:修改一个点的点权,查询链上mex. 输入 第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数.第二行包括n个整数a1...an,代表每个结 ...

  7. bzoj4129 Haruna’s Breakfast 树上带修莫队+分块

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...

  8. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

随机推荐

  1. SQL调优学习之——sqlserver分页从低效到高效

    背景 首先感谢网友@aixuexi 在评论中的提醒,原博文介绍的几种都不是最高效,现已修改加入另一种更高效的方法. 以前都是使用mysql和oracle,对sqlserver的使用不多.最近因项目原因 ...

  2. HBase1.2.0增删改查Scala代码实现

    增删改查工具类 class HbaseUtils { /** * 获取管理员对象 * * @param conf 对hbase client配置一些参数 * @return 返回hbase的HBase ...

  3. HDU1698:Just a Hook(线段树区域更新模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1698 Problem Description In the game of DotA, Pudge’s meat ...

  4. php生成二维码的几种方式

    一些php生成二维码的方式:1.google开放api:2.php类库PHP QR Code:3.libqrencode:4.QRcode Perl CGI & PHP scripts 1.g ...

  5. mysql源码编译安装

    首先去官网http://dev.mysql.com/downloads/mysql/ 下载mysql源码.我下的是5.7.10 源码选择的是 Generic Linux (Architecture I ...

  6. 了解Flask 信号机制

    Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为. pip3 install blinker 1. 内置信号 request_started = ...

  7. Django中间件的5种自定义方法

    阅读目录(Content) Django中间件 自定义中间件 中间件(类)中5种方法 中间件应用场景 回到顶部(go to top) Django中间件 在http请求 到达视图函数之前   和视图函 ...

  8. SQL面试题及答案

    我觉得里面有些答案是不正确的,请只作参考 Student(S#,Sname,Sage,Ssex) 学生表       S#:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别 Cour ...

  9. 基于swing的MySQL可视化界面

    个人记录贴... 代码过烂不宜参考.. 效果展示 1.选择需要打开的数据库,查看数据库下的表. 2.双击打开一个表 3.没有CRUD.... 代码 test-main: import shell.DB ...

  10. c++生成算式并计算(《构建之法》第一章课后第一题)

    c++实现计算器(自动生成算式并计算) 要满足的需求有以下几个: 自动生成随机的四则运算算式,包含括号和小数. 对生成的算式计算出结果. 算式.结果分别存储到不同的文件. 一 生成算式 由上述需求可知 ...