LCT

昨天调试一天没出来,今天推倒重写还是gg了,内心崩溃照着源代码抄,结果发现自己把原树fa和splay的fa一起维护,各种re。。。

其实我们手玩一下,发现其实树的形态变化很小,那么就可以用lct维护了,查询就是相当于查询点到root的点权和,点权为1

删除什么的手画一下就行了

然后我们要用一个数组维护一下原树形态,因为splay是二叉树,可以很方便地维护树的形态,但是一般的树比较麻烦,因为删除儿子什么的的确很烦。这些信息不能再lct上维护,因为lct上fa会变化,里面的fa是splay的fa,不是原树的fa,就破坏了原树形态,所以不能这样维护

然后就是lct各种操作。。。几个月没写都忘了。。。

#include<bits/stdc++.h>
using namespace std;
const int N = , inf = ;
namespace IO
{
const int Maxlen = N * ;
char buf[Maxlen], *C = buf;
int Len;
inline void read_in()
{
Len = fread(C, , Maxlen, stdin);
buf[Len] = '\0';
}
inline void fread(int &x)
{
x = ;
int f = ;
while (*C < '' || '' < *C) { if(*C == '-') f = -; ++C; }
while ('' <= *C && *C <= '') x = (x << ) + (x << ) + *C - '', ++C;
x *= f;
}
inline void read(int &x)
{
x = ;
int f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << ) + (x << ) + c - ''; c = getchar(); }
x *= f;
}
inline void read(long long &x)
{
x = ;
long long f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << 1ll) + (x << 3ll) + c - ''; c = getchar(); }
x *= f;
}
} using namespace IO;
int m, opt, cnt, key, root;
set<pair<int, int> > s;
namespace LCT
{
int st[N];
struct node {
int size, l, r, c[], fa, tag;
} t[N];
inline bool wh(int x) { return t[t[x].fa].c[] == x; }
inline void update(int x) { t[x].size = t[t[x].c[]].size + t[t[x].c[]].size + ; }
inline bool isroot(int x) { return t[t[x].fa].c[] != x && t[t[x].fa].c[] != x; }
inline void pushdown(int x)
{
if(!t[x].tag) return;
swap(t[x].c[], t[x].c[]);
t[t[x].c[]].tag ^= ;
t[t[x].c[]].tag ^= ;
t[x].tag ^= ;
}
inline void up(int x)
{
int top = ;
st[++top] = x;
while(!isroot(x))
{
x = t[x].fa;
st[++top] = x;
}
for(int i = top; i; --i) pushdown(st[i]);
}
inline void rotate(int x)
{
int y = t[x].fa, z = t[y].fa, w = wh(x);
t[x].fa = z;
if(!isroot(y)) t[z].c[wh(y)] = x;
t[y].c[w] = t[x].c[w ^ ];
t[t[x].c[w ^ ]].fa = y;
t[x].c[w ^ ] = y;
t[y].fa = x;
update(y);
update(x);
}
inline void splay(int x)
{
up(x);
while(!isroot(x))
{
if(!isroot(t[x].fa)) rotate(wh(x) == wh(t[x].fa) ? t[x].fa : x);
rotate(x);
}
}
inline void access(int u)
{
for(int f = ; u; f = u, u = t[u].fa)
{
splay(u);
t[u].c[] = f;
update(u);
}
}
inline void rever(int u)
{
access(u);
splay(u);
t[u].tag ^= ;
}
inline void link(int u, int v)
{
if(!u || !v) return;
rever(u);
t[u].fa = v;
}
inline void cut(int u, int v)
{
if(!u || !v) return;
rever(u);
access(v);
splay(v);
t[v].c[] = t[u].fa = ;
update(v);
}
inline void que(int u)
{
rever(root);
access(u);
splay(u);
printf("%d\n", t[u].size);
}
} using LCT :: link; using LCT :: cut; using LCT :: que;
struct info {
int l, r, fa;
} t[N];
inline void insert(int key)
{
pair<int, int> o = make_pair(key, ++cnt);
set<pair<int, int> > :: iterator it1, it2;
it1 = it2 = s.insert(o).first;
int u = , v = , x = cnt;
if(it1 != s.begin()) u = (--it1) -> second;
if(++it2 != s.end()) v = it2 -> second;
if(u == && v == ) root = x;
else if(v && t[v].l == )
{
t[v].l = x;
t[x].fa = v;
link(v, cnt);
}
else if(u && t[u].r == )
{
t[u].r = x;
t[x].fa = u;
link(u, cnt);
}
que(cnt);
}
inline void splay_min()
{
int u = s.begin() -> second, r = t[u].r, p = t[u].fa;
que(u);
if(u == root) return;
cut(u, p);
cut(u, r);
link(p, r);
link(u, root);
t[u].r = root;
t[root].fa = u;
t[r].fa = p;
t[p].l = r;
root = u;
}
inline void splay_max()
{
set<pair<int, int> > :: iterator it = s.end();
int u = (--it) -> second, l = t[u].l, p = t[u].fa;
que(u);
if(u == root) return;
cut(u, p);
cut(u, l);
link(p, l);
link(u, root);
t[u].l = root;
t[root].fa = u;
t[l].fa = p;
t[p].r = l;
root = u;
}
inline void del_min()
{
set<pair<int, int> > :: iterator it = s.begin();
int u = it -> second, r = t[u].r, p = t[u].fa;
que(u);
if(u == root)
{
cut(u, r);
t[r].fa = ;
root = r;
}
else
{
cut(u, p);
cut(u, r);
link(p, r);
t[r].fa = p;
t[p].l = r;
}
s.erase(it);
}
inline void del_max()
{
set<pair<int, int > > :: iterator it = s.end();
int u = (--it) -> second, l = t[u].l, p = t[u].fa;
que(u);
if(u == root)
{
cut(u, l);
t[l].fa = ;
root = l;
}
else
{
cut(u, p);
cut(u, l);
link(p, l);
t[l].fa = p;
t[p].r = l;
}
s.erase(it);
}
int main()
{
// read_in();
read(m);
while(m--)
{
read(opt);
if(opt == ) read(key), insert(key);
if(opt == ) splay_min();
if(opt == ) splay_max();
if(opt == ) del_min();
if(opt == ) del_max();
}
return ;
}

bzoj4825的更多相关文章

  1. 【BZOJ4825】【HNOI2017】单旋(Link-Cut Tree)

    [BZOJ4825][HNOI2017]单旋(Link-Cut Tree) 题面 题面太长,懒得粘过来 题解 既然题目让你写Spaly 那就肯定不是正解 这道题目,让你求的是最大/最小值的深度 如果有 ...

  2. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 667  Solved: 342[Submit][Status][ ...

  3. 【BZOJ4825】[Hnoi2017]单旋 线段树+set

    [BZOJ4825][Hnoi2017]单旋 Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能 ...

  4. BZOJ4825 [Hnoi2017]单旋 【线段树】

    题目链接 BZOJ4825 题解 手模一下操作,会发现一些很优美的性质: 每次旋到根,只有其子树深度不变,剩余点深度\(+1\) 每次旋到根,[最小值为例]右儿子接到其父亲的左儿子,其余点形态不改变, ...

  5. bzoj4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  6. [BZOJ4825][HNOI2017]单旋spaly

    BZOJ Luogu 题目太长了,就不放了. 题解 首先声明一点,无论是splay还是spaly,插入一个新的元素,都要rotate到根!所以说题目也算是给了一个错误示范吧. 我们发现把最值旋转到根并 ...

  7. BZOJ4825 单旋

    分析:一道水题,去年考场发现了特点但是不会splay维护挂了,然后现在我写了个treap. 画一画图就可以解决这道题了,自己试一下. 代码如下: #include<bits/stdc++.h&g ...

  8. BZOJ4825: [Hnoi2017]单旋(Splay)

    题面 传送门 题解 调了好几个小时--指针太难写了-- 因为只单旋最值,我们以单旋\(\min\)为例,那么\(\min\)是没有左子树的,而它旋到根之后,它的深度变为\(1\),它的右子树里所有节点 ...

  9. 【bzoj4825】[Hnoi2017]单旋 线段树+STL-set

    题目描述 H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必修技能.有一天 ...

  10. 刷题总结——单旋(HNOI2017 bzoj4825)

    题目: Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 ...

随机推荐

  1. Hadoop-2.7.1伪分布--安装配置hbase 1.1.2

    hbase-1.1.2下载地址:http://www.eu.apache.org/dist/hbase/stable/hbase-1.1.2-bin.tar.gz 下载之后解压至\usr\local目 ...

  2. CSS Specificity(特殊性)

    CSS的特殊性是非常重要却又经常被忽视的属性,特别是在团队合作下的产品迭代开发中,因为不注重CSS的特殊性最后导致某些代码混乱不堪,这里就把自己对CSS特殊性的认识做一些归纳总结. CSS的特殊性(s ...

  3. cadence中元件所在库

    DISCRETE(分立元件)中 开关: 其中可供选择的这几个比较好 SW PUSHBUTTON SW PUSHBUTTON-DPST 数码管: LDD(开头) LTD(开头) 版权声明:本文为博主原创 ...

  4. 解决Antimalware Service Executable CPU,内存占用高的问题

    1.win键+R键打开运行对话框框,输入gpedit.msc打开本地组策略编辑器(组策略):2.依次打开计算机配置-管理模板-Windows组件-Windows Defender:3.如果要关闭Win ...

  5. 慕课笔记利用css进行布局【三列布局】

    三个div中间自适应,两侧固定大小 <html> <head> <title>三列布局</title> <style type="tex ...

  6. Excel表格如何设置密码 Excel2003/2007/2010设置密码教程

    http://www.wordlm.com/special/2/ 经常使用Excel表格制作报表和一些数据后,我们会给Excel表格设置密码,这样可以很有效的防止数据被盗取.目前Office版本众多, ...

  7. MySQL prepare语句的SQL语法

    MySQL prepare语法: PREPARE statement_name FROM preparable_SQL_statement; /*定义*/ EXECUTE statement_name ...

  8. 安装K/3 Cloud过程中发现的两个新问题。

    卸载掉K/3 Cloud然后重装时出现下面的错误提示: 可能原因: 1.安装目录下的Setup.exe会检查操作系统版本.有些操作系统可能是被串改过注册信息,所以取不到版本信息(有些是因为盗版的原因) ...

  9. Layui栅格系统与后台框架布局

    一.栅格布局规则: 1. 采用 layui-row 来定义行,如:<div class="layui-row"></div> 2. 采用类似 layui-c ...

  10. 深入理解hadoop(一)

    hadoop 前世今生  hadoop最早起源于开源收缩引擎nutch,由dong cutting 贡献,但由于nutch最初的设计不能解决数10亿级别的文件存储和索引而遇到了严重的可扩展性问题,直到 ...