题面

传送门

题解

要不是因为数组版的\(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;
}

LOJ#6038. 「雅礼集训 2017 Day5」远行(LCT)的更多相关文章

  1. LOJ#6038. 「雅礼集训 2017 Day5」远行 [LCT维护子树的直径]

    树的直径一定是原联通块4个里的组合 1.LCT,维护树的直径,这题就做完了 2.直接倍增,lca啥的求求距离,也可以吧- // powered by c++11 // by Isaunoya #inc ...

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

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

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

    分析 代码 #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define ...

  4. [loj6038]「雅礼集训 2017 Day5」远行 lct+并查集

    给你 n 个点,支持 m 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. n≤3×10^5 n≤3×10^5 ,m≤5×10^5 m≤5 ...

  5. [LOJ#6039].「雅礼集训 2017 Day5」珠宝[决策单调性]

    题意 题目链接 分析 注意到本题的 \(C\) 很小,考虑定义一个和 \(C\) 有关的状态. 记 \(f(x,j)\) 表示考虑到了价格为 \(x\) 的物品,一共花费了 \(j\) 元的最大收益. ...

  6. loj#6040. 「雅礼集训 2017 Day5」矩阵(线性代数+递推)

    题面 传送门 题解 我的线代学得跟屎一样看题解跟看天书一样所以不要指望这题我会写题解 这里 //minamoto #include<bits/stdc++.h> #define R reg ...

  7. @loj - 6039@ 「雅礼集训 2017 Day5」珠宝

    目录 @description@ @solution@ @accpeted code@ @details@ @description@ Miranda 准备去市里最有名的珠宝展览会,展览会有可以购买珠 ...

  8. loj #6039 「雅礼集训 2017 Day5」珠宝 分组背包 决策单调性优化

    LINK:珠宝 去年在某个oj上写过这道题 当时懵懂无知wa的不省人事 终于发现这个东西原来是有决策单调性的. 可以发现是一个01背包 但是过不了 冷静分析 01背包的复杂度有下界 如果过不了说明必然 ...

  9. loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...

随机推荐

  1. How To Install Spring IDE In Eclipse

    Spring IDE is a very useful graphical user interface tool adding support for Spring Framework. In th ...

  2. [ML]熵、KL散度、信息增益、互信息-学习笔记

    [ML]熵.KL散度.信息增益.互信息-学习笔记 https://segmentfault.com/a/1190000000641079

  3. Add Strings大整数加法十进制求和 & Add Binary二进制求和

    [抄题]: 以字符串的形式给出两个非负整数 num1 和 num2,返回 num1和 num2 的和. 比如一个50位+一个100位. 给定 num1 = "123",num2 = ...

  4. wcf 调试

    1>在开发环境中调试,我们先在WCF服务上将服务Serivce1.svc设置为启动页面 然后在WCF上Debug中启动新实例 服务就启动起来了 2>wcf发布以后调试,只需在Visual ...

  5. Linq多字段排序

    var q = db.Customers.OrderBy(c => c.City).ThenBy(c => c.ContactName).ToList(); var q = from it ...

  6. 理解数据库中的undo日志、redo日志、检查点

    数据库存放数据的文件,本文称其为data file. 数据库的内容在内存里是有缓存的,这里命名为db buffer.某次操作,我们取了数据库某表格中的数据,这个数据会在内存中缓存一些时间.对这个数据的 ...

  7. [Selenium]计算坐标进行拖拽,重写dragAndDropOffset

    //@author jzhang6 public void dragAndDropOffset(WebDriver driver,WebElement dragableEl, WebElement d ...

  8. qt学习(二) buttong layout spinbox slider 示例

    开启qt5 creator 新建项目 qt widgets 改写main.cpp #include "mainwindow.h" #include <QApplication ...

  9. 关于Android控件EditText的属性InputType的一些经验,java组合多个参数

    关于Android控件EditText的属性InputType的一些经验 2013-11-14 15:08:02|  分类: 默认分类|举报|字号 订阅       1.InputType属性在代码中 ...

  10. foo是什么?

    在英文程序员社区里,foo bar baz这些词是常用于作为占位符而使用的.要查wiki的话,这项更合适:http://en.wikipedia.org/wiki/Metasyntactic_vari ...