ACM多校联赛7 2018 Multi-University Training Contest 7 1009 Tree
【题意概述】
给一棵以1为根的树,树上的每个节点有一个ai值,代表它可以传送到自己的ai倍祖先,如果不存在则传送出这棵树。现在询问某个节点传送出这棵树需要多少步。
【题解】
其实是把“弹飞绵羊”那道题从序列上搬到了树上,解法其实类似。
我们可以用LCT维护传送的关系,若点i存在ai倍祖先,那么就把他们link起来,否则就把i与特殊节点n+1给link起来。
询问某个点要传送多少次时,就是询问这个点到n+1有多远,我们在LCT上取出这一段,查询size即可。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N (100010)
#define ls (c[u][0])
#define rs (c[u][1])
#define LL long long
#define rg register
using namespace std;
int T,n,m,opt,cnt,tot,last[N],k[N],dfn[N],dep[N],p[N][];
struct edge{
int to,pre;
}e[N];
char buf[],*ptr=buf-;
template<typename T>
inline void read(T &k)
{
int f=; k=; char c=*++ptr;
while(c<'' || c>'') c=='-'&&(f=-), c=*++ptr;
while(c<='' && c>='') k=k*+c-'', c=*++ptr;
k*=f;
} struct Link_Cut_Tree{
int top,c[N][],fa[N],rev[N],size[N],q[N];
inline void clear(){
for(rg int i=;i<=n+;i++) c[i][]=c[i][]=size[i]=rev[i]=fa[i]=;
}
inline void pushdown(int u){
if(rev[u]) rev[ls]^=,rev[rs]^=,rev[u]^=,swap(ls,rs);
}
inline void pushup(int u){
size[u]=;
if(ls) size[u]+=size[ls];
if(rs) size[u]+=size[rs];
}
inline bool isroot(int u){
return c[fa[u]][]!=u&&c[fa[u]][]!=u;
}
inline bool which(int u){
return c[fa[u]][]==u;
}
void rotate(int u){
int f=fa[u],gf=fa[f],wh=which(u);
if(!isroot(f)) c[gf][which(f)]=u;
fa[u]=gf; fa[f]=u; fa[c[u][wh^]]=f;
c[f][wh]=c[u][wh^]; c[u][wh^]=f;
pushup(f); pushup(u);
}
void splay(int u){
q[top=]=u;
for(int i=u;!isroot(i);i=fa[i]) q[++top]=fa[i];
for(int i=top;i;i--) pushdown(q[i]);
while(!isroot(u)){
if(!isroot(fa[u])) rotate(which(u)==which(fa[u])?fa[u]:u);
rotate(u);
}
pushup(u);
}
void access(int u){
for(int son=;u;son=u,u=fa[u])
splay(u),c[u][]=son,pushup(u);
}
void makeroot(int u){
access(u); splay(u); rev[u]^=;
}
int find(int u){
access(u); splay(u);
while(ls) u=ls; splay(u);
return u;
}
void split(int x,int y){
makeroot(x); access(y); splay(y);
}
void cut(int x,int y){
int xrt=find(x),yrt=find(y);
if(xrt!=yrt) return;
split(x,y);
if(c[y][]==x) c[y][]=,fa[x]=;
pushup(y);
}
void link(int x,int y){
int xrt=find(x),yrt=find(y);
if(xrt==yrt) return;
makeroot(x); fa[x]=y;
}
}t;
void dfs(int x,int fa){
dfn[x]=++cnt; dep[x]=dep[fa]+; p[x][]=fa;
int tmp=log2(dep[x]);
for (int i=;i<=tmp;i++) p[x][i]=p[p[x][i-]][i-];
for(rg int i=last[x];i;i=e[i].pre) dfs(e[i].to,x);
}
inline int anc(int x,int y){
for(rg int i=;i<=;i++) if(y&(<<i)) x=p[x][i];
return x;
}
inline void Pre(){
for(rg int i=;i<=n;i++) last[i]=;
cnt=tot=;
t.clear();
}
int main(){
fread(buf, , sizeof(buf), stdin);
read(T);
while(T--){
read(n);
Pre();
for(rg int i=;i<=n;i++){
int fa; read(fa);
e[++tot]=(edge){i,last[fa]}; last[fa]=tot;
}
dfs(,);
// for(rg int i=1;i<=n;i++) printf("%d ",dep[i]); puts("dep");
for(rg int i=;i<=n;i++){
read(k[i]);
if(k[i]>=dep[i]) t.link(dfn[i],n+);
else t.link(dfn[i],dfn[anc(i,k[i])]);
}
read(m);
while(m--){
int opt; read(opt);
if(opt==){
int x; read(x);
x=dfn[x];
t.makeroot(x); t.access(n+); t.splay(n+);
printf("%d\n",t.size[n+]-);
}
else{
int x,y; read(x); read(y);
if(k[x]>=dep[x]&&y>=dep[x]) continue;
if(k[x]>=dep[x]) t.cut(dfn[x],n+);
else t.cut(dfn[x],dfn[anc(x,k[x])]);
k[x]=y;
if(k[x]>=dep[x]) t.link(dfn[x],n+);
else t.link(dfn[x],dfn[anc(x,k[x])]);
}
}
}
return ;
}
ACM多校联赛7 2018 Multi-University Training Contest 7 1009 Tree的更多相关文章
- 2018牛客网暑假ACM多校训练赛(第三场)G Coloring Tree 计数,bfs
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-G.html 题目传送门 - 2018牛客多校赛第三场 G ...
- 牛客网暑期ACM多校训练营(第三场)G:Coloring Tree(函数的思想)
之前两次遇到过函数的思想的题,所以这次很敏感就看出来了.可以参考之前的题: https://www.cnblogs.com/hua-dong/p/9291507.html Christmas is c ...
- hdu 6394 Tree (2018 Multi-University Training Contest 7 1009) (树分块+倍增)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=6394 思路:用dfs序处理下树,在用分块,我们只需要维护当前这个点要跳出这个块需要的步数和他跳出这个块去 ...
- 2018 Nowcoder Multi-University Training Contest 2
目录 Contest Info Solutions A. run D. monrey G. transform H. travel I. car J. farm Contest Info Practi ...
- 2018 Nowcoder Multi-University Training Contest 1
Practice Link J. Different Integers 题意: 给出\(n\)个数,每次询问\((l_i, r_i)\),表示\(a_1, \cdots, a_i, a_j, \cdo ...
- 2018 Nowcoder Multi-University Training Contest 5
Practice Link A. gpa 题意: 有\(n\)门课程,每门课程的学分为\(s_i\),绩点为\(c_i\),要求最多删除\(k\)门课程,使得gpa最高. gpa计算方式如下: \[ ...
- 2018 Nowcoder Multi-University Training Contest 10
Practice Link J. Rikka with Nickname 题意: 给出\(n\)个字符串,要求依次合并两个串\(s, t\),满足将\(t\)合并到\(s\)中变成\(r\),使得\( ...
- 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)
2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...
- 2015 HDU 多校联赛 5363 Key Set
2015 HDU 多校联赛 5363 Key Set 题目: http://acm.hdu.edu.cn/showproblem.php? pid=5363 依据前面给出的样例,得出求解公式 fn = ...
随机推荐
- bzoj 4806: 炮【dp】
同1801 注意到一行只能放012个炮,我们只需要知道列的状态,不用状压行 所以设f[i][j][k]表示前i行有j列有1个炮,有k列有2个炮的方案数 然后分情况讨论转移就行了 #include< ...
- bzoj 1599: [Usaco2008 Oct]笨重的石子【枚举】
--我为什么要写这种题解-- 枚举投掷情况即可 #include<iostream> #include<cstdio> using namespace std; int s1, ...
- 使用 typescript 和 canvas 重构snow效果
前言:之前做过一个 snow 效果,但是是直接用 HTML 做的点击此处查看 ,几个星期前,我用 typescript 和 canvas 重构了一下, snow效果是一个很简单的效果,但是用来练手还是 ...
- Springboot 相关注解大全
1.Spring注解 1.@Autowired 标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值:方法使用的参数,自定义类型的值从ioc容器中获取自动装配; Spring利用依赖注入( ...
- 2017杭电多校第六场1011Classes
传送门 Classes Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tota ...
- Laravel5.1学习笔记22 Eloquent 调整修改
Eloquent: Mutators Introduction Accessors & Mutators Date Mutators Attribute Casting Introductio ...
- fragment间的数据传递
今天我将要讲的是fragment间的数据是如何进行传递的.这里我将举个简单的例子. 首先要有个MainActivity,它托管了MainFragment,而MainFragment又托管了DatePi ...
- 安卓TV盒子常见问题以及解决方法
1.为什么requestfocus无效 原因:requestfocus不支持在Touch模式下的Focus; 解法方案:再加一个requestFocusFromTouch函数. 2.摄像头打开问题,调 ...
- MyBatis 之一 简介
什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...
- mysql 存储引擎学习
现在我们常用的MySQL存储引擎主要是两种:InnoDB and MyISAM. 1.MyISAM 执行效率高 不支持事务 不支持外键 每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同, ...