码迷,mamicode.com
首页 > 其他好文 > 详细

3153: Sone1

时间:2015-02-17 22:13:29      阅读:302      评论:0      收藏:0      [点我收藏+]

标签:

这题网上题解比决战好像要多23333

先丢链接跪四位大爷

http://blog.csdn.net/iamzky/article/details/43494481

虽然理解之后大家都讲得很清晰

不过窝看了很久都木有看懂Orz

于是此篇题解尽量平易近人一些吧

窝突然想到一定会有人怀疑我做这种无脑数据结构题的意义……

于是:我的人生,一片无悔~

~~~~~吐槽时间~~~~~

觉得杜教写法不太自然,然后写了个自然的,但是因为要维护子树信息……果断被教做人了

我猜我得调到十点了。一语成谶!

最后甚至都把负数读入优化加上了……还是WA……

我猜我只能明天再说了。再次一语成谶!

要来数据发现木有out,感受到root满满的恶意(我有std我自豪)

妈呀,第一个点就错这么多?我昨天每个梯度都拍了100~1000组啊……

论rand(i-1), i 与 i, rand(i-1)的区别

于是果断花式捉急,感觉简直不会再爱tiao了

调了调之后A了第一个数据,然后测了10个点,都AC了

于是交一发

妈呀,TLE?时间还很诡异?

思考ing……

窝猜是编译超时?我开O2编译需要3s……杜教的0.7s就搞定了……感觉是智商问题

于是乱改了一下,编译时间0.088!好优越!

交上去就CE了233333333333

于是觉得是评测姬傲娇

删了一些东西又交了上去,TLE,妈呀,时间还是诡异!

晚上被UOJ教做人之后无聊点开代码edit-submit

居!然!就!A!了!

白交三次好爽!

你还我的AC ratio!

其实文章里有彩蛋我不会乱说

~~~~~正文时间~~~~~

虽然依赖写的是splay,但是你当然需要会LCT啦~(因为窝写的这两个东西基本没啥差别……)

然后有关toptree是啥之类的问题请参考zky博客……

和上篇文章一样,窝萌考虑LCT

用splay维护链剖分,所以能支持各种链上操作

于是窝萌用一个LCT就可以解决sone1的不带子树部分

于是做完了

当然这是OJ,没有部分分……

窝萌思考一下,如果在LCT上打子树标记,应该怎么下传呢?

吐槽:太sb了!链和节点连出的虚边上传一传不就行了吗!

好吧……

然后怎么传?暴力?

注意到菊花图可以卡到死……

于是窝萌机智一点

用一个二叉树来维护一个节点连出的虚边(注意是一个节点!)

为了复杂度,splay显然

考虑一个事,窝们给每个节点的虚边建了个splay,然后就会有父子关系

为了方便,窝们理所当然应当直接把之前的父子关系改一下(不然你想肿么写程序啊囧……)(如果还是有意见……您以前学数据结构也这样刨根问底求意义吗……)

于是

技术分享

感受一下吧~

考虑 1-2 1-3 2-4 2-5

3:我的父亲是2,isroot()告诉我他是我爸爸

2:孩子,我不是你父亲,我是你的兄弟啊!父亲在我上面,也是isroot()告诉我的

3:那不是我爷爷吗?

所以窝们不能这样

怎么办呢?考虑一种不会出现这种问题的数据结构

线段树!

吐槽:你不是说过是splay了吗!

窝们可以考虑线段树式splay嘛,每次都建出一个中间节点,只保存段的信息,本身不带信息

对比一下:splay:mid+l+r 线段树:l+r

3:我的父亲是一个诡异的节点,他告诉我我真正的父亲在上面

2:真巧,我也是!

在实现上,窝们给每个节点把ch[2]扩充为ch[4]

就可以用ch[2], ch[3]来访问这个节点连出的每个虚儿子了(注意只是这个节点的虚儿子)

设计好框架之后就剩下两部分了

信息合并和标记的维护

窝们把信息做成三个 chain tree all

chain表示这条链上的信息之和,即原LCT中维护的信息

tree表示这条链连出的虚边的信息之和(不丽洁"这条链"请多想想LCT)

all=chain+tree

chain=s[0]->chain+s[1]->chain

tree=s[0]->tree+s[1]->tree+s[2]->all+s[3]->all

all=chain+tree

这个感受一下就明白了

标记做成两个chaintag treetag

chaintag表示对chain的tag(吐槽:废话),即原LCT中的tag

chaintag会对chain和all造成影响

treetag表示对tree的tag(吐槽:废话)

虽然看上去也是废话……不过这个还是有必要认真说说的

窝们不妨规定treetag对链没有管理权

所以chain上的节点不能利用treetag来更新自己的信息,即treetag只会对tree和all造成影响

一种情况除外,即treetag是从上方虚边(手动标tag也算)传下来的

此时窝们要把这个标记分裂为chain+tree

看上去很容易,只需要传一个flag表示一下是怎么下传的,flag==1时再调用一下chainmodify就行了

不过此处有实现细节,即这样会把all改两次……

一种方法比较显然,手动解决即可

但是窝萌可以更取巧一点

chainmodify里直接all=chain+tree就行了

至此,窝们解决了打标记问题

然后是标记下传

chain->s[0] s[1]

tree->s[0], 0 s[1], 0 s[2], 1 s[3], 1

即可(看不懂, 0的请自行反省为啥不仔细看……)

有了update和pushdown,就可以开始写splay了

显然这个没啥难度

唯一注意的就是因为虚边splay和LCT本身是不一样的

所以需要传flag,并讨论一下isroot()

如果你怀疑过splay虚边是否会导致不满足内节点和叶节点的关系问题的话,我可以告诉你(我也怀疑过),

窝们只需要保证只会转内节点就好了,于是内节点记录一个inner就可以解决问题

有了splay,就可以开始写access了

还是可以这样

for (cuts1(p);p->p!=null;splay(p)) cuts1(p->p), links1(p->p, p);

(注意这里p->p的意义不同,是p->p->p->……中第一个不是内节点的节点)

cuts1(p)就是把p->s[1]加入p的虚边splay并同时考虑是否新建内节点 (add(p, p->s[1]))

links1(p, q)就是把q从它的虚边splay中删除,同时维护内节点性质 (del(q)),再把q变为p的s[1]

(即如果他的父亲是内节点,把兄弟扔到父亲位置就行,可以自行脑补一下(如果你问兄弟是否一定存在……多想想?))

当然,这是一种很形式化的写法,实践中窝们可以这样

如果p->p->s[1]!=null,直接用p->p->s[1]代替p,否则再执行del(p)

(当然,杜教永远都有更屌的写法,每次(p=q)->update,最后一发splay(p0),真正的splay!(其实我们之前对p0算是spaly2333))

有了access,就可以开始写reroot了

注意到链不管怎么翻都和虚边没关系(虚边是无序的)

srO vfleaking Orz

此处盗图(盗图时firefox突然卡住,好了之后吓得我赶紧保存了草稿)(恢复之后找了半天没找到,原来是未载入出来23333)

技术分享
所以我们该怎么翻就怎么翻就行了
有了reroot,显然就可以link了
reroot(x), x->p=y?
首先显然窝萌应该用add(y, x)的形式把x加入虚边splay
其次,要维护子树信息好吗?你考虑过y上面的感受吗?
LCT情况:
啥,我有了个虚儿子?关我鸟事?
我需要他信息时他自己不就主动篡位当根然后求我access来了?
AAA树情况:
某丧心病狂OIer:y->p->p,把子树信息交出来!
y->p->p:y->p你倒是赶紧告诉我啊?
y->p:听说我之前有了个虚孙子,那孙子的信息呢?
y:不要问我,其实没人告诉我惹

技术分享

所以我们可以access(y)一下,或者之前就access(y),然后再update一下

两种方法大同小异

接下来我们再接再厉,解决换父亲

我们需要一个findpre(p),找到链上的前驱节点,即一发p->s[0],然后使劲p->s[1]就行了(中途别忘了pushdown)

先access(prep),然后就可以del(p)了,这样p和prep就断绝关系了(p的子树:我们不想这样啊!)

然后现在p已经是root了,直接用link的后半部分接到另一个节点上就好了

然后就是操作和查询部分

链操作参照LCT,注意最后要reroot(root);

子树操作

本蒟蒻写法:access(prep),p->treemodify(tag, 1), access(p);

杜教写法:access(p), modify(p->value) treemodify(p->s[2], 1) treemodify(p->s[3], 1)

两种写法各有千秋(显然杜教智商压制),两种写法的原因请自行思考~

查询就同理了,也是自行思考~

仔细看到这里就可以开始写了,事实上,本篇文章涉及代码的部分大概经常缺少update……请自行思考并补齐……

代码就不贴咯,具体细节自行YY吧~(其实没啥容易写挂的细节了~)

最后感谢每一个忍受本蒟蒻智商并看到最后的神犇

肯定有吐槽"窝萌" "窝们" "我们"混用的,口亨!

3153: Sone1

标签:

原文地址:http://www.cnblogs.com/unknown-shadow/p/4295436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!