4.17 省选模拟赛 远行 LCT 启发式合并 倍增


容易写出nQ的暴力 由于数据是期望的时间 所以直接dfs可以跑的很快 可以拿到70分。
当然 可以进一步优化暴力 使用换根dp 然后可以将暴力优化到n^2.
const int MAXN=300010;
int n,Q,T,len,maxx;
int lin[MAXN],d[MAXN],ver[MAXN<<1],nex[MAXN<<1];
inline void add(int x,int y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
inline void dfs(int x,int y)
{
d[x]=d[y]+1;
maxx=max(maxx,d[x]-1);
go(x)if(tn!=y)dfs(tn,x);
}
int main()
{
freopen("hike.in","r",stdin);
freopen("hike.out","w",stdout);
get(T);get(n);get(Q);
rep(1,Q,i)
{
int op,x,y;
get(op);get(x)^(T*maxx);
if(op==1)get(y)^(T*maxx),add(x,y),add(y,x);
else maxx=0,dfs(x,0),put(maxx);
}
return 0;
}
考虑 离线。可以发现 每次还是需要暴力。
进一步思考 树上和一个点的最远点有什么特殊性质。
不难想到树的直径 可以发现 一个点的最远点一定是直降两端之一.
这个不难证明。分情况讨论 这条路径是否穿过直径来讨论。
那么其实我们要维护一个联通树的直降两端即可。
离线可以先把树给建出来。
然后 合并两个集合的最远点也比较简单 可以证明 新的直径的两端在这4个点之中。
至于证明和上面差不多 也是分类讨论。
这样我们可以利用原树的倍增数组来求两点之间距离。
考虑在线 发现两点距离难求出 考虑启发式合并 然后暴力重新处理倍增数组。
这样每个点最多被重构logn次每次倍增数组的更新 也就是nlog^2+Qlogn 这个虽然已经可以通过了。
但是 考虑更优的做法。
维护树的联通性 容易想到 LCT.
连边的时候 维护一下这个连通块的直径端点即可。两点之间的距离也比较好求。
一个设为根 一个access 最后查splay大小即可。
复杂度 nlogn+Qlogn.
const int MAXN=300010;
int n,Q,T,maxx,top;
int f[MAXN],L[MAXN],s[MAXN],R[MAXN],re[MAXN],fa[MAXN],c[MAXN][2],sz[MAXN];//sz[x]表示x所在splay中的节点个数.
inline int getfather(int x){return x==fa[x]?x:fa[x]=getfather(fa[x]);}
inline int pd(int x){return c[f[x]][1]==x||c[f[x]][0]==x;}
inline void rev(int x)
{
if(!x)return;
swap(c[x][0],c[x][1]);
re[x]^=1;
}
inline void pushup(int x)
{
sz[x]=sz[c[x][0]]+sz[c[x][1]]+1;
}
inline void pushdown(int x){if(re[x])rev(c[x][0]),rev(c[x][1]),re[x]=0;}
inline void rotate(int x)
{
int old=f[x],oldf=f[old],k=c[old][1]==x;
c[old][k]=c[x][k^1];c[x][k^1]=old;
if(pd(old))c[oldf][c[oldf][1]==old]=x;
if(c[old][k])f[c[old][k]]=old;
f[old]=x;f[x]=oldf;pushup(old);
}
inline void splay(int x)
{
int y=x;top=0;
s[++top]=y;
while(pd(y))s[++top]=y=f[y];
while(top)pushdown(s[top--]);
while(pd(x))
{
int old=f[f[x]];
if(pd(f[x]))rotate(((c[f[x]][0]==x)^(c[old][0]==f[x]))?x:f[x]);
rotate(x);
}
pushup(x);return;
}
inline void access(int x)
{
for(int y=0;x;x=f[y=x])
{
splay(x);
c[x][1]=y;
pushup(x);
}
}
inline void make_root(int x)
{
access(x);splay(x);
rev(x);
}
inline int dis(int x,int y)
{
make_root(x);
access(y);
splay(y);
return sz[y];
}
inline void merge(int x,int y)
{
int xx=getfather(x);
int yy=getfather(y);
int s1,s2,s3,s4;
s1=L[xx],s2=L[yy];
s3=R[xx],s4=R[yy];
int l=0,r=0,w=0;
int ww=dis(s1,s2);
if(ww>w)w=ww,l=s1,r=s2;
ww=dis(s1,s3);
if(ww>w)w=ww,l=s1,r=s3;
ww=dis(s1,s4);
if(ww>w)w=ww,l=s1,r=s4;
ww=dis(s2,s3);
if(ww>w)w=ww,l=s2,r=s3;
ww=dis(s2,s4);
if(ww>w)w=ww,l=s2,r=s4;
ww=dis(s3,s4);
if(ww>w)w=ww,l=s3,r=s4;
fa[xx]=yy;L[yy]=l;R[yy]=r;
}
inline void LINK(int x,int y)
{
make_root(x);f[x]=y;
merge(x,y);
}
int main()
{
freopen("1.in","r",stdin);
get(T);get(n);get(Q);
rep(1,n,i)sz[i]=1,L[i]=R[i]=i,fa[i]=i;
rep(1,Q,i)
{
int op,x,y;
get(op);get(x)^(T*maxx);
if(op==1)get(y)^(T*maxx),LINK(x,y);
else
{
int xx=getfather(x);
maxx=max(dis(x,L[xx]),dis(x,R[xx]))-1;
put(maxx);
}
}
return 0;
}
4.17 省选模拟赛 远行 LCT 启发式合并 倍增的更多相关文章
- 5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题
LINK:图 在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy 这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了. 先考虑 如果得到了这么一张图 ...
- 3.28 省选模拟赛 染色 LCT+线段树
发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...
- 6.18 省选模拟赛 字符串 LCT SAM
LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并
[BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...
- @省选模拟赛03/16 - T3@ 超级树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...
- CF827D Best Edge Weight[最小生成树+树剖/LCT/(可并堆/set启发式合并+倍增)]
题意:一张图求每条边边权最多改成多少可以让所有MST都包含这条边. 这题还是要考察Kruskal的贪心过程. 先跑一棵MST出来.然后考虑每条边. 如果他是非树边,要让他Kruskal的时候被选入,必 ...
- BZOJ2888 资源运输(LCT启发式合并)
这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式 ...
- BZOJ.3510.首都(LCT 启发式合并 树的重心)
题目链接 BZOJ 洛谷 详见这. 求所有点到某个点距离和最短,即求树的重心.考虑如何动态维护. 两棵子树合并后的重心一定在两棵树的重心之间那条链上,所以在合并的时候用启发式合并,每合并一个点检查sz ...
随机推荐
- 如何使用SVG及其动画技术为你的 Web 前端开发带来一些新鲜的体验
任何有开发经验的前端工程师都会考虑到不成体系的设备生态所带来的挑战.设备间不同的屏幕尺寸.分辨率和比例使得产品难以提供一致的体验,对于那些对产品有着像素级完美追求的人这种体验差异尤其显著! SVG(可 ...
- java 包装类的使用
1.为什么要有包装类(或封装类) 为了使基本数据类型的变量具有类的特征,引入包装类. 2.基本数据类型与对应的包装类: 3.需要掌握的类型间的转换:(基本数据类型.包装类.String) 应用场景举例 ...
- BZOJ1854 连续攻击游戏 题解
题目 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多 ...
- Xenon's Attack on the Gangs(树规)
题干 Input Output Example Test 1: Test 2: 3 5 1 2 1 2 2 3 1 3 1 4 3 5 3 10 Tips 译成人话 给n个结点,n-1条无向边.即一棵 ...
- java 和 c++ 的三目运算符的区别
转载请注明出处:http://www.cnblogs.com/liangyongrui/p/6348001.html 以前很少用java,就知道java和c++差不多. 今天就踩了一个坑. 不吐糟,直 ...
- 线下---复习day01
目录 1 个人介绍 2 关于编辑器 3 基础串讲 3.1 解释型和编译型 3.2 数据类型 3.2.1 一切皆对象 3.2.1 深浅copy 3.2.3 可变类型与不可变类型 3.3 字符编码 3.4 ...
- CSS3 实现复杂的背景图案
灵活的背景定位 实现效果: 将背景图定位到距离容器底边 10px 且距离右边 20px 的位置. background-position 方案 代码: <div>海盗密码</div& ...
- class文件的基本结构及proxy源码分析二
前文地址:https://www.cnblogs.com/tera/p/13267630.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...
- HTML5提高
HTML5提高 前言 我个人觉得,当你学会了一些最基本的标签其实是够用的,但是在很多网页中可以发现很多新的标签.这个时候不知道它是干嘛的实际上心里是非常没底的,所以在这里我打算写一篇HTML5提高的文 ...
- 纯js实现日期选取功能
平年: 2月-->28天 4,6,9,11月-->30天 1,3,5,7,8,10,12月-->31天 闰年: 2月-->29天 4,6,9,11月-->30天 1,3, ...