Time:2016.09.08
Author:xiaoyimi
转载注明出处谢谢


思路:
这道题相当于把昨天学的树上莫队和带修莫队融合了一下,顺便加了一个mex(未出现的最小自然数)
那么主要问题就是如何求mex
聪哥给出的思路是对[0,n]权值分块,大于n的权值不用管,因为它们永远不会影响答案(显然)
记录每个块的大小,每一次的移动使得该点权值数量+1或-1,记录这个移动对该点权值所在块大小的影响,也就是说如果这个块中该点权值出现次数为0(1),移动使数量+1(-1),那么块大小-1(+1)
这样的话做到了修改是O(1)O(1)的
查询时从小到大找到第一个大小不为0的块,然后在该块内部查找最小权值就行了
块的大小是n23n^\frac 2 3的
带修莫队复杂度为O(n53)O(n^\frac 5 3)
注意修改时要修改该点是否在当前已找的集合内,不能因为它的权值>n就不改了
话说我真的不适合用实时倍增求LCA,看来以后还是回归老本行——ST表吧= =
代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#define M 50005
using namespace std;
int n,m,tot,cnt1,cnt2=1;
int a[M],first[M],last[M],block[M],sum[M],belong[M],siz[M],dfn[M],fa[M][16],dep[M],ans[M];
bool vis[M];
struct edge{int v,next;
}e[M<<1];
struct query{int l,r,t,id;
}q[M];
struct update{int pos,pre,sub;
}c[M];
int in()
{char ch=getchar();int t=0;while (ch>'9'||ch<'0') ch=getchar();while (ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-48,ch=getchar();return t;
}
void add(int x,int y)
{e[++tot]=(edge){y,first[x]};first[x]=tot;e[++tot]=(edge){x,first[y]};first[y]=tot;
}
bool cmp(query a,query b)
{if (block[a.l]==block[b.l]&&a.r==b.r) return a.t<b.t;if (block[a.l]==block[b.l]) return dfn[a.r]<dfn[b.r];return block[a.l]<block[b.l];
}
void dfs(int x)
{dfn[x]=++dfn[0];for (int i=first[x];i;i=e[i].next)if (e[i].v!=fa[x][0])fa[e[i].v][0]=x,dep[e[i].v]=dep[x]+1,dfs(e[i].v);
}
int LCA(int x,int y)
{if (dep[x]<dep[y]) swap(x,y);for (int i=15;i>=0;--i)if (fa[x][i]&&dep[fa[x][i]]>=dep[y])x=fa[x][i];if (x==y) return x;for (int i=15;i>=0;--i)if (fa[x][i]&&fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];return fa[x][0];
}
void Point(int x)
{if (a[x]>n) {vis[x]^=1;return;}if (vis[x]) siz[belong[a[x]]]+=(--sum[a[x]]==0);else siz[belong[a[x]]]-=(++sum[a[x]]==1);vis[x]^=1;
}
void Path(int x,int y)
{if (dep[x]<dep[y]) swap(x,y);for (;dep[x]>dep[y];x=fa[x][0]) Point(x);for (;x!=y;x=fa[x][0],y=fa[y][0]) Point(x),Point(y);
}
int cal()
{int i,j,t=sqrt(n+1);for (i=0;i<=t;++i)if (siz[i]) break;for (j=i*t;j<(i+1)*t;++j)if (!sum[j]) return j;
}
main()
{n=in();m=in();int tt=pow(n,2.0/3.0);for (int i=1;i<=n;++i)last[i]=a[i]=in();for (int i=1;i<n;++i) add(in(),in());dfs(1);for (int i=1;i<=n;++i) block[i]=(dfn[i]+1)/tt;  for (int i=1;i<=15;++i)for (int j=1;j<=n;++j)fa[j][i]=fa[fa[j][i-1]][i-1];tt=sqrt(n+1);for (int i=0;i<=n;++i)belong[i]=i/tt,++siz[belong[i]];int x,y;for (int i=1;i<=m;++i)if (in())q[++cnt1]=(query){in(),in(),cnt2,cnt1};elsex=in(),y=in(),c[++cnt2]=(update){x,last[x],y},last[x]=y;sort(q+1,q+cnt1,cmp);int T=1,L=1,R=1;Point(1);for (int i=1;i<=cnt1;++i){for (int j=T+1;j<=q[i].t;++j)if (vis[c[j].pos]){Point(c[j].pos);a[c[j].pos]=c[j].sub;Point(c[j].pos);}else a[c[j].pos]=c[j].sub;for (int j=T;j>q[i].t;--j)if (vis[c[j].pos]){Point(c[j].pos);a[c[j].pos]=c[j].pre;Point(c[j].pos);}else a[c[j].pos]=c[j].pre;Path(q[i].l,L);Path(q[i].r,R);Point(LCA(L,R));Point(LCA(q[i].l,q[i].r));ans[q[i].id]=cal();T=q[i].t;L=q[i].l;R=q[i].r;}for (int i=1;i<=cnt1;++i) printf("%d\n",ans[i]);
}

【BZOJ4129】Haruna’s Breakfast,树上带修莫队+权值分块求mex相关推荐

  1. P4074-[WC2013]糖果公园【树上带修莫队】

    正题 题目链接:https://www.luogu.com.cn/problem/P4074 题目大意 nnn个点的一颗数,第iii个点有一颗cic_ici​种类的糖. 第iii次获得jjj种类的糖可 ...

  2. LG P4074 [WC2013] 糖果公园(带修莫队,树上莫队)

    LG P4074 [WC2013] 糖果公园 Solution 树上带修莫队,主要还是复习带修莫队和树上莫队. 带修莫队: 带修莫队要先对lll分块的序号作为第一关键字,对rrr分块的序号作为第二关键 ...

  3. 莫队算法 (普通莫队、带修莫队、树上莫队)

    莫队算法 主要基于分块的思想 用结构体记录询问的左右端点及询问编号 (这是一个离线算法) 通过排序优化指针扫描顺序优化时间复杂度 . 1.普通莫队 例题:SP3267 DQUERY - D-query ...

  4. 莫队算法(普通莫队、带修莫队、树上莫队、不删除莫队)学习笔记【理解+套路/核心代码+例题及题解】

    一.理解 我的理解就是巧妙的暴力,利用双指针以及分块思想,巧妙的移动双指针,时间复杂度可以达到O(NlogN). 强推博客:写的又好又全.链接 二.套路 1.普通莫队 [1]核心代码 bool cmp ...

  5. 牛客练习赛85 数学家的迷题 (带修莫队/线段树)

    题意: 1:将a[id]a[id]a[id]的值改为xxx. 2:令t=a[l]×a[l+1]×...×a[r−1]×a[r]t=a[l]×a[l+1]×...×a[r−1]×a[r]t=a[l]×a ...

  6. [国家集训队]数颜色 / 维护队列 (带修莫队模板题)

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

  7. 莫队+带修莫队模板与总结

    以下总结参考了许多大佬们的博客,开篇先(大佬)% 莫队的入门题目主要为莫队和带修莫队在,这里就先在这里总结一下这两类题目的一些属性. 我认为莫队本质是一种比较优化的暴力查找法.在通过分块操作后把复杂度 ...

  8. HDU - 6610 Game(带修莫队)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列 a,sum 为数列 a 的前缀异或和,再给出 m 次操作,每次操作分为两种类型: 1 l r:询问 sum 在区间 [ l , r ] 内有多 ...

  9. 牛客挑战赛48E-速度即转发【带修莫队,分块】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/11161/E 题目大意 给出nnn个数字的一个序列,mmm个操作. 给出l,r,kl,r,kl,r,k,求一个 ...

最新文章

  1. 防抖 节流_每日一题手写函数防抖与节流
  2. DataList中的按钮触发事件的方法的实现
  3. Yii2 使用 Beanstalk 队列系统
  4. AtomicInteger源码注释
  5. javascript   卸载事件(onunload)
  6. python qq模块_Python的nonebot模块如何获取命令发出者的QQ?
  7. Python__模拟实现一个ATM+购物商城程序
  8. pfx证书密码怎么查询_网站是HTTP?10分钟变成HTTPS!域名免费添加配置SSL证书,变成https//环境...
  9. 使用一个环境的或者半径异样消除器来进行异样消除
  10. 诗与远方:无题(八十)- 吸烟而作
  11. bzoj 4002: [JLOI2015]有意义的字符串
  12. SAP License:我对SAP项目实施是这样理解的
  13. Properties集合
  14. HDU 1071 The area
  15. 动态表单 mysql_动态表单实现思路
  16. java基于springboot+vue校园电动自行车管理系统
  17. 伪原创视频软件 视频MD5怎么更改
  18. ENVI图像处理(6):NDVI和植被指数
  19. 每晚夜里自我独行,随处荡,多冰冷,以往为了自我挣扎
  20. java 抽奖系统源码_基于jsp的抽奖系统-JavaEE实现抽奖系统 - java项目源码

热门文章

  1. Scrapy+eChart自动爬取生成网络安全词云
  2. 关于软件定义IT基础设施的未来,深信服是这么思考的
  3. Spring AOP看这个就够了
  4. Kotlin学习笔记23 协程part3 lambda表达式深入 挂起函数 全局协程
  5. Java 并发数据结构
  6. NotImplementedError: Cannot convert a symbolic Tensor报错与解决
  7. 【图像处理基础知识(python+openCV)】——目标检测
  8. java中“53”个关键字(含2个保留字)
  9. C/C++求一个整数的二进制中1的个数
  10. python xrange_Python学习中的知识点(range和xrange)