http://www.spoj.com/problems/DYNALCA/

此题link、cut要求不能换根,当然也保证link时其中一个点必定已经是根。

方法:

void link(Node *x,Node *y)
{
access(x);splay(x);
x->fa=y;
}
void cut(Node *x)
{
access(x);splay(x);
x->ch[]->fa=NULL;x->ch[]=NULL;
}

曾经的错误思路:

void cut(Node *x)
{
access(x->fa);x->fa=NULL;
}

因为此时x->fa不一定是splay维护的序列上x的前一个元素(只是splay上x的父亲罢了,在实际序列中它们的关系可以任意)

求lca?x,y的lca就是先access(x)后,在access(y)的过程中,“最后一次虚边变成实边的位置”。实际也就是access(y)的过程中最后一次的lst

 #include<cstdio>
#include<algorithm>
using namespace std;
namespace LCT
{
struct Node
{
Node *ch[],*fa;
bool rev;
int num;
void upd() {}
void pd()
{
if(rev)
{
swap(ch[],ch[]);
if(ch[]) ch[]->rev^=;
if(ch[]) ch[]->rev^=;
rev=;
}
}
}nodes[];
int mem;
Node *getnode()
{
return nodes+(mem++);
}
bool isroot(Node *x)
{
return (!x->fa)||((x->fa->ch[]!=x)&&(x->fa->ch[]!=x));
}
bool gson(Node *o) {return o==o->fa->ch[];}
void rotate(Node *o,bool d)
{
Node *k=o->ch[!d];if(!isroot(o)) o->fa->ch[gson(o)]=k;
o->ch[!d]=k->ch[d];k->ch[d]=o;
o->upd();k->upd();
k->fa=o->fa;o->fa=k;if(o->ch[!d]) o->ch[!d]->fa=o;
}
Node *st[];int top;
void solvetag(Node *o)
{
while(!isroot(o)) st[++top]=o,o=o->fa;
st[++top]=o;
while(top) st[top--]->pd();
}
void splay(Node *o)
{
solvetag(o);
Node *fa,*fafa;bool d1,d2;
while(!isroot(o))
{
fa=o->fa;d1=(o==fa->ch[]);
if(isroot(fa)) rotate(fa,d1);
else
{
fafa=o->fa->fa;d2=(fa==fafa->ch[]);
if(d1==d2) rotate(fafa,d1),rotate(fa,d1);
else rotate(fa,d1),rotate(fafa,d2);
}
}
}
void access(Node *o)
{
for(Node *lst=NULL;o;lst=o,o=o->fa)
{
splay(o);
o->ch[]=lst;o->upd();
}
}
Node *gtop(Node *o)
{
access(o);splay(o);
for(;o->ch[];o=o->ch[],o->pd());
splay(o);return o;
}
void mtop(Node *o) {access(o);splay(o);o->rev^=;}
void link(Node *x,Node *y)
{
access(x);splay(x);
x->fa=y;
}
//void splay(Node *o,Node *rt)
//{
// if(isroot(rt)) splay(o);
// bool d=gson(rt);Node *t=rt->fa;
// t->ch[d]=NULL;rt->fa=NULL;
// splay(o);
// t->ch[d]=o;o->fa=t;
//}
void cut(Node *x)
{
access(x);splay(x);
x->ch[]->fa=NULL;x->ch[]=NULL;
}
Node *lca(Node *x,Node *y)
{
access(x);Node *lst=NULL;
for(;y;lst=y,y=y->fa)
{
splay(y);
y->ch[]=lst;y->upd();
}
return lst;
}
}
LCT::Node *nd[];
int n,q;char tmp[];
int main()
{
int i,x,y;
scanf("%d%d",&n,&q);
for(i=;i<=n;i++)
{
nd[i]=LCT::getnode();
nd[i]->num=i;
}
while(q--)
{
scanf("%s",tmp);
switch(tmp[])
{
case 'i':
scanf("%d%d",&x,&y);
LCT::link(nd[x],nd[y]);
break;
case 'u':
scanf("%d",&x);
LCT::cut(nd[x]);
break;
case 'c':
scanf("%d%d",&x,&y);
printf("%d\n",LCT::lca(nd[x],nd[y])->num);
break;
}
}
return ;
}

spoj DYNALCA - Dynamic LCA的更多相关文章

  1. SP8791 DYNALCA - Dynamic LCA 解题报告

    SP8791 DYNALCA - Dynamic LCA 有一个森林最初由 \(n (1 \le n \le 100000)\) 个互不相连的点构成 你需要处理以下操作: link A B:添加从顶点 ...

  2. 【题解】Luogu SP8791 DYNALCA - Dynamic LCA

    原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 这道题的难点就在如何求LCA: 我们珂以先对其中一个点进行access操作,然后对另一个点进行access操作,因为L ...

  3. SP8791 DYNALCA - Dynamic LCA

    \(\color{#0066ff}{ 题目描述 }\) 有一个森林最初由 n (\(1 \le n \le 100000\))n(\(1\leq n\leq 100000\)) 个互不相连的点构成 你 ...

  4. CodeForcesGym 100512D Dynamic LCA

    Dynamic LCA Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForcesGym. ...

  5. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  6. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

  7. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  8. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  9. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

随机推荐

  1. Node.js+Web TWAIN,实现Web文档扫描和图像上传

      目录(?)[+] 通过Dynamic Web TWAIN SDK和Node.js的组合,只需要几行代码就可以实现在浏览器中控制扫描仪,获取图像后上传到远程服务器. 原文:Document Imag ...

  2. BloomFilter学习

    看大数据面试题,看到BloomFilter,找了篇文章学习一下: http://www.cnblogs.com/heaad/archive/2011/01/02/1924195.html Bloom ...

  3. Linux驱动开发:USB驱动之usb_skel分析

    在学习了这么些天的驱动之后,个人觉得驱动就是个架构的问题,只要把架构弄清楚了 然后往里面添砖加瓦就可以了,所以似乎看起来不是太困难,但也许是是我经验不足吧,这只能算是个人浅见了 这两天在学习USB驱动 ...

  4. html5摇一摇代码优化

    首先对DeviceMotionEvent进行优化: 去除没用的代码,又一次封装DeviceMotionEven if(window.DeviceMotionEvent) { var speed = 2 ...

  5. MaterialImageView

    https://github.com/zhaozhentao/MaterialImageView

  6. boost的内存管理

    smart_ptr raii ( Resource Acquisition Is Initialization ) 智能指针系列的都统称为smart_ptr.包含c++98标准的auto_ptr 智能 ...

  7. ExtJs 中获取 radiobutton 的值

    ExtJs中使用radiobutton,想在ExtJs本身代码中(注意,不是在后台喔)获取 radioButton 的值,居然发现很难,无从下手的感觉.后来在网上寻寻觅觅,痛苦摸索之后,真是大跌眼镜. ...

  8. su 和 su- 会影响环境变量

    大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行,这就需要从当前用户切换到root用户,Linux中切换用户的命令是su或su -,下面就su命令和 ...

  9. res_d_l =[{'contents':d.contents,'href':d.attrs['href']} for d in rd] 泛型

    from selenium import webdriverfrom selenium.webdriver.chrome.options import Options# from selenium.w ...

  10. Lightoj 1014 - Ifter Party

    I have an Ifter party at the 5th day of Ramadan for the contestants. For this reason I have invited  ...