爆栈的处理方法

爆栈指递归中,存储的信息量大于系统栈的内存。

信息量包括元素编号,每一层中开的变量。

和递归的层数正相关。

(虽然noip一般开栈)

1.手写栈

while(top){

  int x=sta[top];

  for(each son)

  if(has son){

    //blablabla

    sta[++top]=son;

    hd[x]=e[i].nxt;

  }

  else{

    //blablabla

    sta[top--]=0;

  }

}

可以用一个弧优化,使得每次儿子回溯后,父亲往下的边的访问直接继续。

这样复杂度就对了。

如果son回溯后,在到下一个son之前,还要做一些事情,那就用个pair,结构体什么的,讨论一下情况即可。

 

 

2.bfs序求dfs序

用bfs求dfs序(先序遍历序)

相同点:

先出来father的编号再出来son的编号。根节点都是1号。

区别:子树连续访问pk儿子连续访问。

联系:就差一个size

bfs求bfs序,再倒序记录每个点的size

然后,遍历bfs序。

这时x的fa一定已经求出了dfs序。

如果上一个点的fa和这个点的fa不同,那么x一定是x的fa的第一个儿子,到了fa之后就先访问x。dfn[x]=dfn[fa[x]]+1

如果上一个点的fa和这个点的fa相同,那么x一定是上一个点的后兄弟。dfn[x]=dfn[las]+size[las]

理解就是,dfs时会先遍历las的整个子树。并且下一个就一定是x了。

 

3.本地手动开栈:

#pragma GCC ("-W1,--stack=128000000)手动开栈。

 

posted @ 2018-10-22 11:02  *Miracle*  阅读(3535)  评论(0编辑  收藏  举报