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 ...
随机推荐
- [转]linux下释放文件内存
在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好.但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了. ...
- mysql的存储过程与事务入门
存储过程是:通过一系列的SQL语句, 根据传入的参数(也可以没有), 通过简单的调用, 完成比单个SQL语句更复杂的功能, 存储在数据库服务器端,只需要编译过一次之后再次使用都不需要再进行编译.主要对 ...
- iOS AOP编程思想及实践
什么是 AOP Wikipedia 上的 AOP 定义: In computing, aspect-oriented programming (AOP) is a programming paradi ...
- xp下对dinput8.dll 游戏键盘输入的模拟 非函数hook
https://www.xuebuyuan.com/833929.html 很多游戏或者3d模拟软件为了更好的支持外设使用directinput作为输入接口调用.那么如果要模拟鼠标或键盘来控制游戏或者 ...
- 使用kendynet构建异步redis访问服务
使用kendynet构建异步redis访问服务 最近开始在kendynet上开发手游服务端,游戏类型是生存挑战类的,要存储的数据结构和类型都比较简单,于是选择了用redis做存储,数据类型使用stri ...
- 日记整理---->2017-05-14
学习一下知识吧,好久没有写博客了.如果他总为别人撑伞,你又何苦非为他等在雨中. 学习的知识内容 一.关于base64的图片问题 byte[] decode = Base64.base64ToByteA ...
- 【Python系列】python关键字、符号、数据类型等分类
https://github.com/AndyFlower/Python/blob/master/sample/python前言如下部分为python关键字,操作符号,格式字符.转义字符等,以后有时间 ...
- myisam与innodb索引比较
MyISAM支持全文索引(FULLTEXT).压缩索引,InnoDB不支持 InnoDB支持事务,MyISAM不支持 MyISAM顺序储存数据,索引叶子节点保存对应数据行地址,辅助索引很主键索引相差无 ...
- ThinkPHP-5.0.23新的RCE漏洞测试和POC
TP5新RCE漏洞 昨天又是周五,讨厌周五曝漏洞,还得又得加班,算了,还是先验证一波.新的TP5RCE,据说发现者因为上次的RCE,于是又审计了代码,结果发现的.TP5也成了万人轮啊. 测试 环境搭建 ...
- vue实现按需加载(懒加载)
1.router文件中使用 export default new Router({ routes: [{ path: '/', name: 'Post', component: () => im ...