题面

传送门

题解

要不是因为数组版的\(LCT\)跑得实在太慢我至于去学指针版的么……而且指针版的完全看不懂啊……

首先有两个结论

1.与一个点距离最大的点为任意一条直径的两个端点之一

2.两棵树之间连一条边新树直径的端点一定是第一棵树直径的两个端点和第二颗树直径的两个端点这四个点之二

然后用并查集维护联通块的直径就行了。注意因为这里强制在线,所以得用\(LCT\)来维护距离

并不建议看代码因为这个代码非常难懂哪怕我加满注释您都不一定看得懂

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
inline int getop(){R char ch;while((ch=getc())>'9'||ch<'0');return ch-'0';}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=3e5+5;
struct node;typedef node* ptr;
inline void swap(R ptr &x,R ptr &y){R ptr t=x;x=y,y=t;}
inline int max(R int &x,R int &y){return x>y?x:y;}
struct node{ptr fa,lc,rc;int s;bool r;inline node();inline void ppd(){swap(lc,rc),r^=1;}inline void pd(){if(r)lc->ppd(),rc->ppd(),r=0;}inline ptr upd(){return s=lc->s+rc->s+1,this;}
}e[N];
inline node::node(){fa=lc=rc=e;}
inline bool isrt(R ptr p){return p->fa->lc!=p&&p->fa->rc!=p;}
void rotate(ptr p){ptr s=p->fa,t=s->fa;if(!isrt(s))(t->lc==s?t->lc:t->rc)=p;p->fa=t,s->fa=p;if(s->lc==p)s->lc=p->rc,p->rc->fa=s,p->rc=s->upd();else s->rc=p->lc,p->lc->fa=s,p->lc=s->upd();
}
void push(ptr p){if(!isrt(p))push(p->fa);p->pd();}
ptr splay(ptr p){push(p);while(!isrt(p)){if(!isrt(p->fa))rotate(p==p->fa->lc^p->fa==p->fa->fa->lc?p:p->fa);rotate(p);}return p->upd();
}
ptr exp(ptr p){ptr s=e;while(p!=e)splay(p)->rc=s,s=p->upd(),p=p->fa;return s;
}
ptr exp(R int i){return exp(e+i);}
struct qwq{int s,t,d;inline qwq(){}inline qwq(R int ss,R int tt,R int dd):s(ss),t(tt),d(dd){}
}p[N];
int ga[N];
int find(int x){return ga[x]==x?x:ga[x]=find(ga[x]);}
void link(int i,int j){exp(i)->ppd(),exp(j)->ppd();//上面两步已经完成了makeroot操作了 //虽然还没有把i和j给splay上去 int u=find(i),v=find(j);int s1=exp(p[u].s)->s,s2=exp(p[u].t)->s;//分别计算直径的两个端点到根节点的距离//注意这里的距离 是指它们之间的点数,也包括根节点 int s3=exp(p[v].s)->s,s4=exp(p[v].t)->s;qwq a=p[u];if(s1+s3-1>a.d)a=qwq(p[u].s,p[v].s,s1+s3-1);if(s1+s4-1>a.d)a=qwq(p[u].s,p[v].t,s1+s4-1);if(s2+s3-1>a.d)a=qwq(p[u].t,p[v].s,s2+s3-1);if(s2+s4-1>a.d)a=qwq(p[u].t,p[v].t,s2+s4-1);if(a.d>p[v].d)p[v]=a;ga[u]=v,splay(e+i)->fa=e+j;
}
int ask(int i){exp(i)->ppd();int u=find(i),s1=exp(p[u].s)->s,s2=exp(p[u].t)->s;return max(s1,s2)-1;
}
int n,ty,q,ans,op,u,v;
int main(){
//  freopen("testdata.in","r",stdin);ty=read(),n=read(),q=read();fp(i,1,n)ga[i]=i,p[i]=qwq(i,i,0);while(q--){op=read(),u=read()^(ans*ty);if(op==1)v=read()^(ans*ty),link(u,v);else print(ans=ask(u));}return Ot(),0;
}

转载于:https://www.cnblogs.com/bztMinamoto/p/10713567.html

LOJ#6038. 「雅礼集训 2017 Day5」远行(LCT)相关推荐

  1. loj 6038「雅礼集训 2017 Day5」远行

    http://www.elijahqi.win/archives/3236 题目描述 Miranda 生活的城市有 N NN 个小镇,一开始小镇间没有任何道路连接.随着经济发现,小镇之间陆续建起了一些 ...

  2. 【刷题】LOJ 6038 「雅礼集训 2017 Day5」远行

    题目描述 Miranda 生活的城市有 \(N\) 个小镇,一开始小镇间没有任何道路连接.随着经济发现,小镇之间陆续建起了一些双向的道路但是由于经济不太发达,在建设过程中,会保证对于任意两个小镇,最多 ...

  3. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  4. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 -- 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  5. Loj 6036 「雅礼集训 2017 Day4」编码 - 2-sat

    题目传送门 唯一的传送门 题目大意 给定$n$个串,每个串只包含 '0','1','?' ,其中 '?' 至多在每个串中出现1次,它可以被替换为 '0' 或 '1' .问是否可能任意两个不同的串不满足 ...

  6. LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)

    题面 传送门 题解 答案就是\(S(n-k,k)\times {n-1\choose k-1}\) 其中\(S(n,m)\)表示左边\(n\)个点,右边\(m\)个点的完全二分图的生成树个数,它的值为 ...

  7. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

  8. 「雅礼集训 2017 Day5」珠宝

    题目描述 Miranda 准备去市里最有名的珠宝展览会,展览会有可以购买珠宝,但可惜的是只能现金支付,Miranda 十分纠结究竟要带多少的现金,假如现金带多了,就会比较危险,假如带少了,看到想买的右 ...

  9. LOJ #6052. 「雅礼集训 2017 Day11」DIV

    完了我是数学姿势越来越弱了,感觉这种CXRdalao秒掉的题我都要做好久 一些前置推导 首先我们很容易得出\((a+bi)(c+di)=k \Leftrightarrow ac-bd=k,ad+bc= ...

  10. LOJ #6051. 「雅礼集训 2017 Day11」PATH

    完了感觉最近留了好多坑的说,这题也是模模糊糊地会一点 首先我们发现题目要求的是单调不上升的序列个数,那么一个套路就是用值减去下标 然后考虑连续位置的限制,这个我们做一个置换然后尽量向后取 这样拿值和位 ...

最新文章

  1. AI CC2019软件安装教程
  2. python中几种交换2个变量的值的方法
  3. Apache Kafka-SpringBoot整合Kafka发送复杂对象
  4. rust游戏解封了吗_柚子君宾馆爬墙听隔壁声,潇天傲解封不罢休!继续专场嘲讽散打哥...
  5. sougou ubuntu 优麒麟_搜狗输入法 Linux – V2.3 版发布,完美适配优麒麟 19.10
  6. QT之 Hello World
  7. delphi7 获取dll的类_上传quot;定时任务quot;获取系统权限
  8. 直播软件APP源码,一套完整的直播软件源码解决方案
  9. ArcMap中无法读取NetCDF数据
  10. Django模型、模板和视图
  11. 【软考系统架构设计师】2010年下系统架构师案例分析历年真题
  12. 鱼眼摄像机弊端及应用
  13. 撒金币动画android,Anime Gacha
  14. weka,FP,priori
  15. dcos里面跑jenkins的问题
  16. 十种做Flash游戏赚钱的方法
  17. Android Studio下Terminal窗口Window下cmd黑窗口中使用adb命令调试精炼详解
  18. Linux文件复制、移动、删除等操作命令
  19. php如何让图片铺满屏幕,如何解决js获取屏幕大小并且让图片自适应的方法
  20. COSAGPS进行GAMIT基线解算数据的平差

热门文章

  1. X11/XWindow更改属性代码
  2. 围棋三番棋,得第二局得胜
  3. static library libs/libvpx/libvpx.a is not portable!
  4. Git第一次提交代码的操作
  5. 4站地铁50多分钟,百度地图怎么算的
  6. 编译OpenJDK12:valid values for --with-freetype are system and bundled
  7. OpenJDK8和OpenJDK8u的差异
  8. MySQL用C访问的示例代码
  9. linux中posix共享内存,Linux 共享内存(POSIX)
  10. C++前序中序后序非递归遍历