bzoj 4129 Haruna’s Breakfast 树上莫队
按照dfs序分块,莫队乱搞
再套个权值分块
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100005
using namespace std; int e=1,head[N];
struct edge{
int u,v,next;
}ed[2*N];
void add(int u,int v){
ed[e].u=u; ed[e].v=v;
ed[e].next=head[u];
head[u]=e++;
} int qq,cc,n,m,nn,nnn,be[N],bb[N],gy[N],dep[N],fa[N],anc[N][18];
bool vis[N];
int num[N],all[N],ll[N],rr[N];
struct Query{
int l,r,id,tim,ans;
}qr[N];
void add_query(int x,int y){
qr[++qq].l=x;
qr[qq].r=y;
qr[qq].id=qq;
qr[qq].tim=cc;
}
bool cmp1(Query a,Query b){
if(be[a.l]==be[b.l])
return be[a.r]<be[b.r];
return be[a.l]<be[b.l];
}
bool cmp2(Query a,Query b){
return a.id<b.id;
} struct Change{
int pos,nxt,pre;
}ch[N];
void add_change(int x,int y){
ch[++cc].pos=x;
ch[cc].nxt=y;
ch[cc].pre=gy[x];
gy[x]=y;
} int stack[N],top=0,cnt;
void dfs(int x){
dep[x]=dep[fa[x]]+1;
for(int i=1;i<=15;i++)
anc[x][i]=anc[anc[x][i-1]][i-1];
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa[x]) continue;
fa[v]=anc[v][0]=x;
dfs(v);
if(top>=nn){
++cnt;
while(top)
be[stack[top--]]=cnt;
}
}
stack[++top]=x;
if(x==1&&top){
++cnt;
while(top)
be[stack[top--]]=cnt;
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);//dep[x]>=dep[y]
for(int i=15;~i;i--)
if(dep[anc[x][i]]>=dep[y])
x=anc[x][i];
if(x==y) return x;
for(int i=15;~i;i--)
if(anc[x][i]!=anc[y][i]){
x=anc[x][i];
y=anc[y][i];
}
return anc[x][0];
}
void pls(int x){
vis[x]=1;
if(gy[x]>n+1) return;
if(++num[gy[x]]==1)
all[bb[gy[x]]]++;
}
void reduc(int x){
vis[x]=0;
if(gy[x]>n) return;
if(--num[gy[x]]==0)
all[bb[gy[x]]]--;
}
void update(int x){
if(vis[x]){
reduc(x);
return ;
}
if(!vis[x]) pls(x);
}
void change(int x,int y){
int now=lca(x,y);
//printf("x==%d y==%d now==%d\n",x,y,now);
while(x!=now)
update(x),x=fa[x];
while(y!=now)
update(y),y=fa[y];
} int main()
{
scanf("%d%d",&n,&m);
nn=(int)pow(n,2.0/3.0);
nnn=(int)sqrt(n);
for(int i=1;i<=n;i++){
scanf("%d",&gy[i]);
bb[i]=i/nnn+1;
}
bb[0]=1;
for(int i=1;i<=bb[n];i++){
ll[i]=(i-1)*nnn;
rr[i]=i*nnn-1;
}
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v); add(v,u);
}
dfs(1);
int opt,a,b;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&opt,&a,&b);
if(opt==0) add_change(a,b);
if(opt==1) add_query(a,b);
}
sort(qr+1,qr+qq+1,cmp1);
int l=1,r=1,t=cc,old,now;
update(1);
for(int i=1;i<=qq;i++)
{
//printf("%d %d %d %d\n",qr[i].id,qr[i].tim,qr[i].l,qr[i].r);
old=lca(l,r);
now=lca(qr[i].l,qr[i].r);
change(qr[i].l,l);
change(qr[i].r,r);
update(old); update(now);
for(int j=t+1;j<=qr[i].tim;j++){
if(dep[ch[j].pos]>=dep[now]&&(lca(ch[j].pos,qr[i].l)==ch[j].pos||lca(ch[j].pos,qr[i].r)==ch[j].pos)){
update(ch[j].pos); gy[ch[j].pos]=ch[j].nxt; update(ch[j].pos);
}
gy[ch[j].pos]=ch[j].nxt;
}
for(int j=t;j>qr[i].tim;j--){
if(dep[ch[j].pos]>=dep[now]&&(lca(ch[j].pos,qr[i].l)==ch[j].pos||lca(ch[j].pos,qr[i].r)==ch[j].pos)){
update(ch[j].pos); gy[ch[j].pos]=ch[j].pre; update(ch[j].pos);
}
gy[ch[j].pos]=ch[j].pre;
}
t=qr[i].tim; l=qr[i].l; r=qr[i].r;
for(int j=1;j<=bb[n];j++)
if(all[j]!=rr[j]-ll[j]+1){
for(int k=ll[j];k<=rr[j];k++){
if(!num[k]){
qr[i].ans=k;
break;
}
}
break;
}
//for(int j=0;j<=n;j++) printf("k==%d num==%d\n",j,num[j]);
//printf("ans================%d\n",qr[i].ans);
}
sort(qr+1,qr+qq+1,cmp2);
for(int i=1;i<=qq;i++)
printf("%d\n",qr[i].ans);
return 0;
}
bzoj 4129 Haruna’s Breakfast 树上莫队的更多相关文章
- BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
- BZOJ 4129 Haruna’s Breakfast ( 树上带修莫队 )
题面 求树上某路径上最小的没出现过的权值,有单点修改 添加链接描述 分析 树上带修莫队板题,问题是怎么求最小的没出现过的权值. 因为只有nnn个点,所以没出现过的最小值一定在[0,n][0,n][0, ...
- BZOJ 4129 Haruna’s Breakfast (分块 + 带修莫队)
4129: Haruna’s Breakfast Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 835 Solved: 409[Submit][St ...
- BZOJ 4129 Haruna’s Breakfast
传送门 同样是树上莫队 只不过要求一个集合的mex,这里可以使用分块,可以在根号时间内得出解 /************************************************** P ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...
- 【BZOJ4129】Haruna’s Breakfast(树上莫队)
[BZOJ4129]Haruna's Breakfast(树上莫队) 题面 BZOJ Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了 ...
- bzoj4129 Haruna’s Breakfast 树上带修莫队+分块
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...
- [BZOJ4129]Haruna’s Breakfast(树上带修改莫队)
BZOJ3585,BZOJ2120,BZOJ3757三合一. 对于树上路径问题,树链剖分难以处理的时候,就用树上带修改莫队. 这里的MEX问题,使用BZOJ3585的分块方法,平衡了时间复杂度. 剩下 ...
随机推荐
- WPF中使用后台代码来控制TreeView的选择项(SelectedItem)以及展开节点操作
首先为TreeView控件制作一个Style: <Style x:Key="LibraryTreeViewItemStyle" TargetType="{x:Typ ...
- OC实现带弹跳动画按钮的界面控制器view
很多应用都有带弹跳动画发布界面,这里用一个 UIViewController 实现这种效果,外界只要 modal出不带动画这个控制器就可以实现 #import "BSPublishVC.h& ...
- RunTime运行时在iOS中的应用之UITextField占位符placeholder
RunTime运行时机制 runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的Objective-C代码中, 程序运行过程时, 其实最终 ...
- BAT面试技巧
很多人都质疑面试前去google一下面试题,是否有用....其实真实情况往往是这样:前台告诉经理,有个面试者来了,经理一拍头:啊!差点忘了!拿起电话:小谢,你有空吧,帮忙面个试! 小谢答应后,goog ...
- WebAPP移动前端性能优化规范和设计指导
- MySQL 的索引优化
索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,所以大数据量建立索引是非常有必要的.My ...
- JavaScript函数节流和函数防抖之间的区别
一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...
- 在Java中谈尾递归--尾递归和垃圾回收的比较(转载)
我不是故意在JAVA中谈尾递归的,因为在JAVA中谈尾递归真的是要绕好几个弯,只是我确实只有JAVA学得比较好,虽然确实C是在学校学过还考了90+,真学得没自学的JAVA好 不过也是因为要绕几个弯,所 ...
- 基于DP的LCS(最长公共子序列)问题
最长公共子序列,即给出两个序列,给出最长的公共序列,例如: 序列1 understand 序列2 underground 最长公共序列undernd,长度为7 一般这类问题很适合使用动态规划,其动态规 ...
- 如何利用Python网络爬虫爬取微信朋友圈动态--附代码(下)
前天给大家分享了如何利用Python网络爬虫爬取微信朋友圈数据的上篇(理论篇),今天给大家分享一下代码实现(实战篇),接着上篇往下继续深入. 一.代码实现 1.修改Scrapy项目中的items.py ...