【题意】给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值。n,m<=5*10^4,0<=ai<=10^9。

【算法】树分块+带修改莫队算法

【题解】和【BZOJ】3052: [wc2013]糖果公园 树分块+待修改莫队算法差不多。

区别在于如何处理树链信息。考虑对值域分块,由于>n的数字没用,所以对[0,n]分块,维护每一块所含数字个数。

这样就可以O(1)单点修改,O(√n)查询。(扫描到第一块所含数字不满的块,再块内扫描到第一个没出现的数字)。

复杂度O(n^(5/3)+n^(3/2))。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int belong[maxn],be[maxn],first[maxn],tot,cnt,top,deep[maxn],f[maxn][],B,Q;
int st[maxn],c[maxn],n,m,c0,c1,sz[maxn],num[maxn],mx,pre[maxn],ANS[maxn];
bool vis[maxn];
struct edge{int v,from;}e[maxn*];
struct mo{int x,y,pre;}a[maxn];
struct que{int x,y,t,id;}b[maxn];
bool cmp(que a,que b){return belong[a.x]<belong[b.x]||(belong[a.x]==belong[b.x]&&belong[a.y]<belong[b.y])||
(belong[a.x]==belong[b.x]&&belong[a.y]==belong[b.y]&&a.t<b.t);}
void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
void dfs(int x,int fa){
int p=top;
for(int j=;(<<j)<=deep[x];j++)f[x][j]=f[f[x][j-]][j-];
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
deep[e[i].v]=deep[x]+;
f[e[i].v][]=x;
dfs(e[i].v,x);
if(top-p>=B){
cnt++;
while(top>p)belong[st[top--]]=cnt;
}
}
st[++top]=x;//
}
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
int d=deep[x]-deep[y];
for(int j=;(<<j)<=d;j++)if(d&(<<j))x=f[x][j];
if(x==y)return x;
for(int j=;j>=;j--)if((<<j)<=deep[x]&&f[x][j]!=f[y][j])x=f[x][j],y=f[y][j];
return f[x][];
}
void rev(int x){
if(c[x]>n){vis[x]^=;return;}
if(!vis[x])sz[be[c[x]]]+=(++num[c[x]]==);
else sz[be[c[x]]]-=(--num[c[x]]==);
vis[x]^=;
}
void modify(int x,int y){
if(!vis[x])c[x]=y;
else rev(x),c[x]=y,rev(x);
}
void solve(int x,int y){
while(x!=y){
if(deep[x]>deep[y])rev(x),x=f[x][];
else rev(y),y=f[y][];
}
}
int calc(){
int r;
for(r=;r<mx;r++)if(sz[r]<Q)break;
for(int i=r*Q;i<=n;i++)if(num[i]==)return i;
return n;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&c[i]),pre[i]=c[i];
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
insert(u,v);insert(v,u);
}
B=(int)(pow(n,2.0/)*0.5)+;
Q=(int)(sqrt(n))+;
for(int i=;i<=n;i++)be[i]=i/Q;mx=n/Q;
dfs(,);
while(top)belong[st[top--]]=cnt;
for(int i=;i<=m;i++){
int s,u,v;
scanf("%d%d%d",&s,&u,&v);
if(!s)a[++c0]=(mo){u,v,pre[u]},pre[u]=v;
else{
if(belong[u]>belong[v])swap(u,v);
b[++c1]=(que){u,v,c0,c1};
}
}
sort(b+,b+c1+,cmp);
for(int i=;i<=b[].t;i++)modify(a[i].x,a[i].y);
solve(b[].x,b[].y);
int L=lca(b[].x,b[].y);
rev(L);ANS[b[].id]=calc();rev(L);
for(int i=;i<=c1;i++){///
for(int j=b[i-].t+;j<=b[i].t;j++)modify(a[j].x,a[j].y);
for(int j=b[i-].t;j>b[i].t;j--)modify(a[j].x,a[j].pre);
solve(b[i-].x,b[i].x);solve(b[i-].y,b[i].y);
int L=lca(b[i].x,b[i].y);
rev(L);ANS[b[i].id]=calc();rev(L);
}
for(int i=;i<=c1;i++)printf("%d\n",ANS[i]);
return ;
}

记得询问先处理1,然后从2开始枚举。

【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法的更多相关文章

  1. 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法

    [题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...

  2. 莫队 [洛谷2709] 小B的询问[洛谷1903]【模板】分块/带修改莫队(数颜色)

    莫队--------一个优雅的暴力 莫队是一个可以在O(n√n)内求出绝大部分无修改的离线的区间问题的答案(只要问题满足转移是O(1)的)即你已知区间[l,r]的解,能在O(1)的时间内求出[l-1, ...

  3. AC日记——【模板】分块/带修改莫队(数颜色) 洛谷 P1903

    [模板]分块/带修改莫队(数颜色) 思路: 带修改莫队: (伏地膜xxy): 代码: #include <bits/stdc++.h> using namespace std; #defi ...

  4. 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 653  Solved: 283[Submit][Status][Discuss] ...

  5. 洛谷 P1903 BZOJ 2120 清橙 A1274【模板】分块/带修改莫队(数颜色)(周奕超)

    试题来源 2011中国国家集训队命题答辩 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔 ...

  6. P1903 【模板】分块/带修改莫队(数颜色)

    题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...

  7. bzoj 3052: [wc2013]糖果公园【树上带修改莫队】

    参考:http://blog.csdn.net/lych_cys/article/details/50845832 把树变成dfs括号序的形式,注意这个是不包含lca的(除非lca是两点中的一个) 然 ...

  8. 洛谷 P1903 【模板】分块/带修改莫队(数颜色)

    题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...

  9. luogu1903 【模板】分块/带修改莫队(数颜色)

    莫队算法模板 推荐阅读这篇博客 #include <algorithm> #include <iostream> #include <cstdio> #includ ...

随机推荐

  1. DB2 日志

    跟Oracle类似DB2也分为两个模式,日志循环vs归档日志,也就是非归档和归档模式,下面对这两种模式做简单的介绍. 日志循环 日志循环是默认方式,也就是非归档模式,这种模式只支持backup off ...

  2. OSG学习:LOD、数据分页、动态调度

    LOD(level of detail):是指根据物体模型的结点在显示环境中所处的位置和重要度,决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算.在OSG的场景结点组织结 ...

  3. ViewController 视图控制器的常用方法

    ViewController 视图控制器 ,是控制界面的控制器,通俗的来说,就是管理我们界面的大boss,视图控制器里面包含了视图,下面举个例子,让视图在两个视图上调转. 定义一个视图控制器: MyV ...

  4. 【final】评价①

    飞天小女警添加猜你喜欢功能,个人很喜欢.当推荐产品不喜欢的时候还有其他的选择,很人性化. 金州勇士将管理人员的角色分开,使整个系统的分工更明确,也更清晰. 新蜂的俄罗斯方块随着等级的提升有直观的颜色变 ...

  5. js滚动异步加载数据的思路

    <body> <div style="width:200px; height:1000px; border:1px solid red;" id="to ...

  6. HTTP协议 结构,get post 区别(阿里面试)

    如果需要想了解相关的TCP的协议结构,底层架构,以及每次面试必问的三次握手,四次挥手可以 参考:TCP协议详解7层和4层解析(美团面试,阿里面试) 尤其是三次握手,四次挥手 具体发送的报文和状态都要掌 ...

  7. rxjs5.X系列 —— ErrorHandling/Condition/Mathematical系列 api 笔记

    欢迎指导与讨论 : ) 前言 本文是笔者翻译 RxJS 5.X 官网各类operation操作系列的的第四篇 —— ErrorHanding异常处理.Condition Operator情况操作.Ma ...

  8. 【C++】深度探索C++对象模型读书笔记--Data语意学(The Semantics of data)

    1. 一个空类的大小是1 byte.这是为了让这一类的两个对象得以在内存中配置独一无二的地址. 2. Nonstatic data member 放置的是“个别的class object”感兴趣的数据 ...

  9. 【Python】Python发展历史

    起源 Python的作者,Guido von Rossum,荷兰人.1982年,Guido从阿姆斯特丹大学获得了数学和计算机硕士学位.然而,尽管他算得上是一位数学家,但他更加享受计算机带来的乐趣.用他 ...

  10. Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)

    题意:给出一张完全图,所有的边的边权都是 y,现在给出图的一个生成树,将生成树上的边的边权改为 x,求一条距离最短的哈密顿路径. 先考虑x>=y的情况,那么应该尽量不走生成树上的边,如果生成树上 ...