bzoj4129 Haruna’s Breakfast 莫队
这个思想不难理解了前面几个就能懂
但是代码比较复杂,大概会和之前几次碰到难题的时候一样,一步步思考下去,然后把难点分成好几个板块讲下qwq
首先读入这颗树,预处理下lca,然后就分块,这个时候就会碰到第一个难点了
第一个点是,怎么分块
对不起无法理解无法证明为什么是酱婶的,但是实现并不难qwq
首先明确的是块的大小是n0.45不要问我为什么不会:D
就是如果这个块内的任意俩点距离都小于块的大小,就可以放在一块中
然后这个可以通过dfs+栈实现
代码大概就酱婶的↓
inline void dfs(int x)
{
int gg=cnt;
for(register int i=head[x];i;i=edge[i].next)
{
if(fa[x][]==edge[i].to)continue;
fa[edge[i].to][]=x;deep[edge[i].to]=deep[x]+;
rp(j,,)fa[edge[i].to][j]=fa[fa[edge[i].to][j-]][j-];
dfs(edge[i].to);
if(cnt-gg>=len){++tot;while(cnt!=gg)bl[stck[cnt--]]=tot;}
}
stck[++cnt]=x;
}qwq
分块搞完之后就可以读入修改和询问了,这里就没有太难感觉,用俩结构体就是了
然后排序,就和带修莫队是一样的,不讲
然后就开始解决问题
这个板子题有个很美滋滋的事儿,就是它修改起来特别简单,一路照着链走就是了,然后^修改就是了
但是又会遇到第二个,不算难点,大概是坑点qwq
第二个点是,lca很委屈
显然lca那个点会求两次
所以要另外求一次
那就另外搞个lca的函数求一下就欧克辽嘛
代码也比较简单嘛qwq
inline int lca(int x,int y)
{
if(x==y)return x;if(deep[x]<deep[y])swap(x,y);
my(i,,)if(deep[fa[x][i]]>=deep[y])x=fa[x][i];
my(i,,)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return x==y?x:fa[x][];
}就是个板子嘛QAQ
umm布星我发现我理解还是不够透彻,关于那个直接移动那儿我依然没有理解得十分清楚
所以先咕着了QAQ可能要过一阵子再写QAQ
over
然后原来的代码先放着但是显然是有错误的?先放着趴之后方便改,实在不想全部重码遍了QAQ
#include<bits/stdc++.h>
using namespace std;
#define rp(i,x,y) for(register int i=x;i<=y;++i)
#define my(i,x,y) for(register int i=x;i>=y;--i) const int N=+,sqtN=+;
int now,tot,n,m,c[N],cc[N],len,bl[N],ans[N],cnt;
//umm还是分别写下分工?nm读入不说,c读入和之后莫队修改颜色操作在此处,cc用来搞oldnew的,len是树上块的长度
//bl是树上分块的belong,ans存答案.now是当前时间点,tot开始是树上栈的个数后来是change个数,cnt开始是存边的后来是存栈内元素个数的
int bll[N],cjkcjk,lenlen,num[N],sum[sqtN],sz[sqtN];
//这一行是存查答案那个操作的,bll表示答案的属于,cjkcjk是答案的块个数,lenlen是答案的块的长度,num是每个数个数,sum表示这个块有多少个存在的,sz表示这个块有几个数
int head[N],deep[N],fa[N][],stck[sqtN];
//这一行是专门搞那个边的,比较中规中矩没什么可说的
bool vis[N];
//vis存的是这个点在链上嘛
struct qest{int l,r,id,tim;}q[N];
struct chan{int p,nc,oc;}cg[N];
struct ed{int to,next;}edge[N]; inline int read()
{
char ch=getchar();int x=;bool y=;
while(ch!='-' && (ch<'' || ch>''))ch=getchar();
if(ch=='-')ch=getchar(),y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=getchar();
return y?x:-x;
}
inline void add(int x,int y){edge[++cnt].to=x;edge[cnt].next=head[y];head[y]=cnt;}
inline bool cmp(qest gold,qest genius){return bl[gold.l]==bl[genius.l]?bl[gold.r]==bl[genius.r]?gold.tim<genius.tim:bl[gold.r]<bl[genius.r]:bl[gold.l]<bl[genius.l];}
inline void ad(int x){sum[bll[x]]+=(++num[x])==;}
inline void dl(int x){sum[bll[x]]-=(--num[x])==;}
inline int as(){rp(i,,cjkcjk)if(sum[i]!=sz[i])rp(j,lenlen*(i-),lenlen*(i-)+sz[i]-)if(!num[j])return j;}
inline void update(int x){if(vis[x])dl(c[x]);else ad(c[x]);vis[x]^=;}
inline void change(int x,int y){if(vis[x])dl(c[x]),ad(y);c[x]=y;}
inline void dfs(int x)
{
int gg=cnt;
for(register int i=head[x];i;i=edge[i].next)
{
if(fa[x][]==edge[i].to)continue;
fa[edge[i].to][]=x;deep[edge[i].to]=deep[x]+;
rp(j,,)fa[edge[i].to][j]=fa[fa[edge[i].to][j-]][j-];
dfs(edge[i].to);
if(cnt-gg>=len){++tot;while(cnt!=gg)bl[stck[cnt--]]=tot;}
}
stck[++cnt]=x;
}
inline int lca(int x,int y)
{
if(x==y)return x;if(deep[x]<deep[y])swap(x,y);
my(i,,)if(deep[fa[x][i]]>=deep[y])x=fa[x][i];
my(i,,)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return x==y?x:fa[x][];
}
inline void move(int x,int y)
{
if(x==y)return;if(deep[x]<deep[y])swap(x,y);
while(deep[x]!=deep[y])update(x),x=fa[x][];
while(x!=y)update(x),update(y),x=fa[x][],y=fa[y][];
}
inline void pre()
{
n=read();m=read();len=pow(n,0.45);
lenlen=sqrt(n);cjkcjk=n/lenlen+;rp(i,,n)bll[i]=(i-)/lenlen+,++sz[(i-)/lenlen+];
rp(i,,n)c[i]=read(),cc[i]=c[i];
rp(i,,n-){int t1=read(),t2=read();add(t1,t2);add(t2,t1);}
cnt=;rp(i,,)fa[][i]=;dfs();++tot;while(cnt)bl[stck[cnt--]]=tot;cnt=;tot=;
rp(i,,m)
{
bool op=read();
if(op)q[i-tot].l=read(),q[i-tot].r=read(),q[i-tot].id=i-tot,q[i-tot].tim=tot;
else cg[++tot].p=read(),cg[tot].nc=read(),cg[tot].oc=cc[cg[tot].p],cc[cg[tot].p]=cg[tot].nc;
}
sort(q+,q++m-tot,cmp);
} int main()
{
pre();
move(q[].l,q[].r);update(lca(q[].l,q[].r));ans[q[].id]=as();
// printf("id=%d l=%d r=%d lca=%d\n",q[1].id,q[1].l,q[1].r,lca(q[1].l,q[1].r));rp(i,1,n)if(vis[i])printf("%d-%d ",i,c[i]);printf("\n\n");
update(lca(q[].l,q[].r));
// printf("\n------------\n");
rp(i,,m-tot)
{
while(now<q[i].tim)change(cg[now+].p,cg[now+].nc),++now;
while(now>q[i].tim)change(cg[now].p,cg[now].oc),--now;
move(q[i].l,q[i-].l);move(q[i].r,q[i-].r);
update(lca(q[i].l,q[i].r));
ans[q[i].id]=as();
// printf("id=%d l=%d r=%d lca=%d ans=%d\n",q[i].id,q[i].l,q[i].r,lca(q[i].l,q[i].r),ans[q[i].id]);
// rp(j,1,n)if(vis[j])printf("%d-%d ",j,c[j]);printf("\n\n");
update(lca(q[i].l,q[i].r));
// printf("\n------------\n");
}
rp(i,,m-tot)printf("%d\n",ans[i]);
return ;
}
太难受了挑了半天然后T了TT
...难受死了不想做这题了,先这样趴至少样例过了?
很烦躁了QAQ
bzoj4129 Haruna’s Breakfast 莫队的更多相关文章
- [BZOJ4129]Haruna’s Breakfast(树上带修改莫队)
BZOJ3585,BZOJ2120,BZOJ3757三合一. 对于树上路径问题,树链剖分难以处理的时候,就用树上带修改莫队. 这里的MEX问题,使用BZOJ3585的分块方法,平衡了时间复杂度. 剩下 ...
- bzoj4129 Haruna’s Breakfast 树上带修莫队+分块
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...
- BZOJ4129: Haruna’s Breakfast
Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵 树上,每个结点都有一样食材,Shimakaze要考验一下她. 每个食材都有一个美 ...
- 【树上莫队】【带修莫队】【权值分块】bzoj4129 Haruna’s Breakfast
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...
- 【BZOJ4129】Haruna’s Breakfast(树上莫队)
[BZOJ4129]Haruna's Breakfast(树上莫队) 题面 BZOJ Description Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了 ...
- 【bzoj4129】Haruna’s Breakfast 带修改树上莫队+分块
题目描述 给出一棵树,点有点权.支持两种操作:修改一个点的点权,查询链上mex. 输入 第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数.第二行包括n个整数a1...an,代表每个结 ...
- 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 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
- bzoj 4129 Haruna’s Breakfast 树上莫队
按照dfs序分块,莫队乱搞 再套个权值分块 #include<cstdio> #include<iostream> #include<cstring> #inclu ...
随机推荐
- FFmpeg X264的preset和tune
鉴于x264的参数众多,各种参数的配合复杂,为了使用者方便,x264建议如无特别需要可使用preset和tune设置.这套开发者推荐的参数较为合理,可在此基础上在调整一些具体参数以符合自己需要,手动设 ...
- 在 Ubuntu 中安装 MySQL 指南
安装MySQL 在Ubuntu上可以使用Ubuntu Software Center或者apt命令来安装MySQL,两种方式都十分方便. 1. 使用Ubuntu Software Center:打开U ...
- cannot access android.support.v4.app.BaseFragmentActivityJB的解决
//implementation 'com.android.support:appcompat-v7:26.1.0' 改成implementation 'com.android.support:app ...
- [原]如何为SqlServer2008数据库分配用户
前言: 当一个项目完成后,为了数据安全,总会对该项目的数据库分配一个用户,应该说总会创建一个用户来管理这个数据库,并且这个用户只能管理这个数据库.搞了好多次,每次都忘记怎么设置,所以写一篇博文记录一下 ...
- 微信小程序的wx-charts插件
还有就是可以使用一些小程序的插件,比如wx-charts. 先来看一下网上对这个插件的评价: 目前在github上有1804颗星,使用的比较广泛. github地址:https://github.co ...
- Android学习之适配器SimpleCursorAdapter
三. SimpleCursorAdapter与SimpleAdapter用法相近.只是将List对象换成了Cursor对象.而且SimpleCursorAdapter类构造方法的第四个参数from ...
- 转 Mysql性能优化教程
Mysql性能优化教程 背景及目标 厦门游家公司(4399.com)用于员工培训和分享. 针对用户群为已经使用过mysql环境,并有一定开发经验的工程师 针对高并发,海量数据的互联网环境. 本文语言为 ...
- 禁用Visual Studio 2013的Browser Link功能 -调试不断请求http://localhost:6154/c4ad1c693ebf428283832eaa827f9c6e/arterySignalR/poll?transport=longPolling...
关于禁用查到的解决: 作者:donny945 https://my.oschina.net/ind/blog/359003 今天浏览器调试代码的时候,一直出现以下的请求,导致需要看的请求都被淹没了,之 ...
- 【vue学习】vue中怎么引用laydate.js日期插件
此贴意在解决一个妹子的问题 https://q.cnblogs.com/q/101462 下载js包 http://www.layui.com/laydate/ 将laydate下载的包解压放入sta ...
- 云计算设计模式(六)——命令和查询职责分离(CQRS)模式
云计算设计模式(六)——命令和查询职责分离(CQRS)模式 隔离,通过使用不同的接口,从操作读取数据更新数据的操作.这种模式可以最大限度地提高性能,可扩展性和安全性;支持系统在通过较高的灵活性,时间的 ...