【题意】给定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. Oracle win64_12g 安装

    1.Oracle win64_12g 安装 1.下载安装包:这里需要自己注册一下,然后就可以登录下载软件了. 下载地址: http://www.oracle.com/technetwork/datab ...

  2. Visual C++ 8.0对象布局

    哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...

  3. Swift-闭包使用及解决循环引用问题

    Swift中闭包使用参考OC中block使用,基本一致 // 闭包类型 首先写(参数列表)->(返回值类型) func loadData(callBack : (jsonData:String) ...

  4. Docker 技术 介绍

    https://github.com/docker/docker 实现用户空间隔离的技术:名称空间(NameSpace),CGroup(控制组) 什么是NameSpace::简单的理解就是,每一个虚拟 ...

  5. BIND的安装配置

    简介 bind是dns协议的一种实现,也就是说,bind仅仅是实现DNS协议的一种应用程序 bind运行后的进程名叫named,不叫bind bind bind的配置文件在:/etc/named.co ...

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

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

  7. Objective - C 之类目

    一.类目(category):为已有的类(可以是系统类,也可以是自定义类)添加公有的新的方法: 例如:为系统已有的NSString类添加一个比较字符串大小的方法 1.创建过程: 2.NSString ...

  8. 【final】Scrum站立会议第2次....11.20

    小组名称:nice! 组长:李权 成员:于淼  刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.9    12:00——12:30 地点:传媒西楼220室 本次对fnal阶段 ...

  9. Android四大组件之Intent(续2)

    1.你如何通过一个intent来唤醒activity? this.startActivity(intent,request);      2.什么是显式.隐式的intents? 显式:指定组件名,通常 ...

  10. 【转载】Java中的锁机制 synchronized & 偏向锁 & 轻量级锁 & 重量级锁 & 各自优缺点及场景 & AtomicReference

    参考文章: http://blog.csdn.net/chen77716/article/details/6618779 目前在Java中存在两种锁机制:synchronized和Lock,Lock接 ...