【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法
【题意】给定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 树分块+带修改莫队算法的更多相关文章
- 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法
[题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...
- 莫队 [洛谷2709] 小B的询问[洛谷1903]【模板】分块/带修改莫队(数颜色)
莫队--------一个优雅的暴力 莫队是一个可以在O(n√n)内求出绝大部分无修改的离线的区间问题的答案(只要问题满足转移是O(1)的)即你已知区间[l,r]的解,能在O(1)的时间内求出[l-1, ...
- AC日记——【模板】分块/带修改莫队(数颜色) 洛谷 P1903
[模板]分块/带修改莫队(数颜色) 思路: 带修改莫队: (伏地膜xxy): 代码: #include <bits/stdc++.h> using namespace std; #defi ...
- 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 653 Solved: 283[Submit][Status][Discuss] ...
- 洛谷 P1903 BZOJ 2120 清橙 A1274【模板】分块/带修改莫队(数颜色)(周奕超)
试题来源 2011中国国家集训队命题答辩 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔 ...
- P1903 【模板】分块/带修改莫队(数颜色)
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
- bzoj 3052: [wc2013]糖果公园【树上带修改莫队】
参考:http://blog.csdn.net/lych_cys/article/details/50845832 把树变成dfs括号序的形式,注意这个是不包含lca的(除非lca是两点中的一个) 然 ...
- 洛谷 P1903 【模板】分块/带修改莫队(数颜色)
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
- luogu1903 【模板】分块/带修改莫队(数颜色)
莫队算法模板 推荐阅读这篇博客 #include <algorithm> #include <iostream> #include <cstdio> #includ ...
随机推荐
- DWZ-JUI+UEditor第二次不显示,UEditor异步加载第二次不显示的解决方案
使用UEditor-1.4.3中遇到第一次跳转到使用UEditor的界面后,编辑器加载正常,返回后第二次再跳转到这个界面就出现UEditor无法正常加载, 也没百度到答案,看UEditor源码,发现这 ...
- 1."问吧APP"客户需求调查分析
产品名称:问吧 产品功能:实时提问回答和搜索 开发原因:任何人都会遇到问题,网上虽然有很多回答,但是互联网的信息错综复杂,开发这个APP就是为了让网络求助更加的合理有效,清除网络上的垃圾信息. 为知大 ...
- Java实现的词频统计——单元测试
前言:本次测试过程中发现了几个未知字符,这里将其转化为十六进制码对其加以区分. 1)保存统计结果的Result文件中显示如图: 2)将其复制到eclipse环境下的切分方法StringTokenize ...
- nest
d3.nest d3.nest表示一种嵌套结构.之所以成为嵌套是因为可以指定多个key访问器,这些访问器是一层一层嵌套的. 作用 将数组中的元素对象,按照key方法指定的属性,分组为层次结构.与SQL ...
- FZU2127_养鸡场
题目的意思为要你求出满足三边范围条件且周长为n的三角形的数目. 其实做法是直接枚举最短边,然后就可以知道第二条边的取值范围,同时根据给定的范围缩小范围. 同时根据第二条边的范围推出第三条边的范围,再次 ...
- 【loj6307】「雅礼国庆 2017 Day1」Clique 贪心
题目描述 数轴上有 $n$ 个点,第 $i$ 个点的坐标为 $x_i$ 权值为 $w_i$ .两个点 $i,j$ 之间存在一条边当且仅当 $|x_i−x_j|\le w_i+w_j$ . 你需要求出这 ...
- P1939 【模板】矩阵加速(数列)
题目描述 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007(10^9+7)取余的值. 输入输出格式 输入格式: 第一行一 ...
- Django之form表单提交并验证
1.提交的时候会报错 2. 需要在setting里面注释掉一句话,关闭跨站请求检查. 3. 注释掉以后,理论上就不报错了.可我还是卡壳了. 4. 通过在网上找方法,修复错误. 原因:表单action字 ...
- 【BZOJ4889】不勤劳的图书管理员(树套树)
[BZOJ4889]不勤劳的图书管理员(树套树) 题面 又是权限题,烦死了 洛谷真好 题解 分开考虑每一次交换产生的贡献. 假设交换\((x,y)\) 检查\(x\)与\(y\)对于区间\([x+1, ...
- IPC$入侵大全
0x01 ipc$的定义 IPC$(Internet Process Connection)是共享"命名管道"的资源(大家都是这么说的),它是为了让进程间通信而开放的命名管道,可 ...