CF1137F Matches Are Not a Child's Play 题解
以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前。
记每个点子树中的最大值为 \(f_x\),那么一个点的排名,首先就需要加上 \(<f_x\) 的所有值,记对应 \(f_x\) 的点为 \(y\),那么 \(y\) 一定会一路上来删掉 \(x\)。
所以一个点排名就是 \(<f_x\) 的所有值,再加上 \(x,y\) 之间的距离。
考虑如何维护修改,设上一个根是 \(rt\),新根是 \(x\),那么等价于一次换根,需要将 \(x\) 到 \(rt\) 这条路径 cover 上 \(p_{rt}\),同时改掉 \(x\) 的值。
可以使用 ODT + 树剖维护。
Code
const int N=2e5+5;
int n,m;
vi G[N];
int dep[N],siz[N],top[N],son[N],dfn[N],fat[N],dfc,p[N*2],rp[N*2];
void dfs1(int u,int fa) {
dep[u]=dep[fa]+1,siz[u]=1,fat[u]=fa;
for(int v:G[u]) if(v!=fa) {
dfs1(v,u),siz[u]+=siz[v];
p[u]=max(p[u],p[v]);
if(siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int tp,int fa) {
top[u]=tp,dfn[u]=++dfc;
if(son[u]==0) return;
dfs2(son[u],tp,u);
for(int v:G[u]) if(v!=fa&&v!=son[u]) dfs2(v,v,u);
}
int bit[2*N];
void add(int x,int v) { for(;x<=n+m;x+=(x&-x)) bit[x]+=v; }
int ask(int x) { int ret=0; for(;x;x-=(x&-x)) ret+=bit[x]; return ret; }
struct node {
int l,r,v;
node() {}
node(int L,int R,int V) { l=L,r=R,v=V; }
bool operator < (const node &a) const { return l<a.l; }
};
set<node> odt;
auto spilt(int p) {
auto it=odt.lower_bound(node(p,-1,0));
if(it!=odt.end()&&it->l==p) return it;
--it;
int l=it->l,r=it->r,v=it->v;
odt.erase(it),odt.insert(node(l,p-1,v));
return odt.insert(node(p,r,v)).fi;
}
void cover(int l,int r,int v) {
auto itr=spilt(r+1),itl=spilt(l);
for(auto it=itl;it!=itr;it=odt.erase(it)) add(it->v,-((it->r)-(it->l)+1));
add(v,r-l+1),odt.insert(node(l,r,v));
}
void update(int u,int v,int w) {
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cover(dfn[top[u]],dfn[u],w),u=fat[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
cover(dfn[u],dfn[v],w);
}
int lca(int u,int v) {
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
u=fat[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int dist(int u,int v) { return dep[u]+dep[v]-2*dep[lca(u,v)]+1; }
int query(int x) {
auto pos=odt.upper_bound(node(dfn[x],-1,0));
int val=prev(pos)->v;
return ask(val-1)+dist(x,rp[val]);
}
int main() {
n=read(),m=read();
FOR(i,1,n-1) {
int x=read(),y=read();
G[x].pb(y),G[y].pb(x);
}
FOR(i,1,n) p[i]=rp[i]=i;
int rt=n,mx=n;
dfs1(n,0),dfs2(n,n,0);
FOR(i,1,n) add(p[i],1),odt.insert(node(dfn[i],dfn[i],p[i]));
FOR(i,1,m) {
string ch; cin>>ch;
int u=read();
if(ch[0]=='1') {
if(u!=rt) update(rt,u,mx);
++mx,cover(dfn[u],dfn[u],mx),rp[mx]=rt=u;
}
else if(ch[0]=='2') printf("%d\n",query(u));
else { int v=read(); printf("%d\n",query(u)>query(v)?v:u);}
}
}
CF1137F Matches Are Not a Child's Play 题解的更多相关文章
- CF1137F Matches Are Not a Child's Play(LCT思维题)
题目 CF1137F 很有意思的题目 做法 直接考虑带修改的做法,上一次最大值为u,这次修改v,则最大值为v了 我们发现:\(u-v\)这条链会留到最后,序列里的其他元素相对位置不变,这条链会\(u\ ...
- CF1137F Matches Are Not a Child's Play(树链剖分)
题面 我们定义一棵树的删除序列为:每一次将树中编号最小的叶子删掉,将该节点编号加入到当前序列的最末端,最后只剩下一个节点时将该节点的编号加入到结尾. 例如对于上图中的树,它的删除序列为:2 4 3 1 ...
- 【树链剖分 ODT】cf1137F. Matches Are Not a Child's Play
孔爷的杂题系列:LCT清新题/ODT模板题 题目大意 定义一颗无根树的燃烧序列为:每次选取编号最小的叶子节点形成的序列. 要求支持操作:查询一个点$u$在燃烧序列中的排名:将一个点的编号变成最大 $n ...
- CF1137F Matches Are Not a Child's Play
我们定义一棵树的删除序列为:每一次将树中编号最小的叶子删掉,将该节点编号加入到当前序列的最末端,最后只剩下一个节点时将该节点的编号加入到结尾.现在给出一棵n个节点的树,有m次操作: up v:将v号节 ...
- [cf1137F]Matches Are Not a Child's Pla
显然compare操作可以通过两次when操作实现,以下仅考虑前两种操作 为了方便,将优先级最高的节点作为根,显然根最后才会被删除 接下来,不断找到剩下的节点中(包括根)优先级最高的节点,将其到其所在 ...
- [Codeforces1137F]Matches Are Not a Child's Play——LCT+树状数组
题目链接: [Codeforces1137F]Matches Are Not a Child's Play 题目大意: 我们定义一棵树的删除序列为:每一次将树中编号最小的叶子删掉,将该节点编号加入到当 ...
- Codeforces 1137F Matches Are Not a Child's Play [LCT]
Codeforces 很好,通过这题对LCT的理解又深了一层. 思路 (有人说这是套路题,然而我没有见过/kk) 首先发现,删点可以从根那里往下删,非常难受,所以把权值最大的点提为根. 然后考虑\(x ...
- Codeforces 1137F - Matches Are Not a Child's Play(LCT)
Codeforces 题面传送门 & 洛谷题面传送门 考虑将一个点 \(x\) 的编号变为当前所有点编号最大值 \(+1\) 会对每个点的删除时间产生怎么样的影响.由于编号最大的点肯定是最后一 ...
- The Child and Zoo 题解
题目描述 Of course our child likes walking in a zoo. The zoo has n areas, that are numbered from 1 to n. ...
- LCT[Link-Cut-Tree学习笔记]
部分摘抄于 FlashHu candy99 所以文章篇幅较长 请有足够的耐心(不是 其实不用学好splay再学LCT的-/kk (至少现在我平衡树靠fhq) 如果学splay的话- 也许我菜吧-LCT ...
随机推荐
- Django框架:10、Ajax补充说明、多对多三种创建方法、Django内置序列化组件、批量操作数据方法、分页器思路、form组件
Django框架 目录 Django框架 一.Ajax补充说明 1.针对前端回调函数接受值的说明 二.多对多三种创建方式 1.自动创建 2.纯手动创建 3.半自动创建 三.Django内置序列化组件 ...
- 由char和byte的关系引申出去——总结一下java中的字符编码相关知识
由char和byte的关系引申出去--总结一下java中的字符编码相关知识 一.字符编码 手持两把锟斤拷,口中直呼烫烫烫 在文章伊始,先来复习一下计算机中关于编码的一些基础知识,着重理清以下几 ...
- JSONObject 相关
/** * 将json转为对应实体类 */ public static Object jsonToJavaObj(String json, Class cs) { return jsonToJavaO ...
- P8622 [蓝桥杯 2014 国 B] 生物芯片
简要题意 有 \(N\) 个二进制数,编号为 \(1\sim N\),初始时都是 \(0\).博士进行了 \(N-1\) 次操作,在第 \(i\) 次操作时,会将 \(1\sim N\) 中所有编号为 ...
- 刷题笔记——3002.买图书 & 2763.计算(a+b)/c的值
题目1 3002.买图书 代码 while True: try: n,m=map(float,input().strip().split()) if(n==10 and m==1): print('{ ...
- python利用matplotlib生成迷宫
起因 我想要写一个项目叫python迷宫游戏,需求是玩家能和机器对抗率先走出迷宫,至少要有两个等级的电脑. 慢慢来,首先迷宫游戏需要有一个迷宫并展示出来,这便是这篇博客的目的 假设迷宫使用0表示点,1 ...
- excel文件 实现自动处理数据的功能
目录 问题描述: 解决方案: 一.SQL查询 二.SQL.python处理 三.python处理 四.优化python处理 1.手动执行代码 2.开机自动执行代码 对比四种方案: 总结: 问题描述: ...
- css边框,盒子模型、浮动、定位
边框,盒子模型.浮动.定位 一.边框 border-width : 边框宽度 border-style : 边框样式 1.solid 实线 2.none 无边框 3.dotted 点状虚线边框 4.d ...
- GPS定位解决偏差
目录 GPS定位解决偏差 开篇 实践 1.解决思路以及步骤 2.实践出真理! 3.上坐标系之间的代码. 希望大家:点赞,留言,关注咯~ 唠家常 今日推荐都在文章中了 GPS定位解决偏差 开篇 大家都知 ...
- 【分析笔记】SiliconLabs EFR32BG22 Bluetooth Mesh SensorClient 源码分析
硬件环境: SLTB010A(BRD4184A Rev A02 / EFR32BG22C224F512IM40) 软件环境: SimplicityStudio5/gecko_sdk_3.2.3 分析工 ...