hack 线段树合并

CF1009F Dominant Indices

World_Creater @ 2023-12-05 20:38:29

RT,通过在“每次线段树合并垃圾回收无用空间”(也就是这里的做法)的做法空间复杂度并不是线性的。

我们构造一棵形如这样的二叉树:
一直这样长到 n 为之。

然后通过对输入边集顺序的构造,使得在 dfs 过程中每次都先访问右子树,这样就会导致在第一次合并操作开始前,所有叶子已经被访问到而插入了值,插入 \dfrac{n}{2} 次那么空间直接 \mathcal{O}(n\log n),然后就爆了。

附一个输入数据生成器:

#include<bits/stdc++.h>
using namespace std;
const int n=1000000;
int main()
{
    cout<<n<<"\n";
    int m=n-1;
    int now=1,cnt=1;
    while(m)
    {
        cnt++;
        cout<<now<<" "<<cnt<<"\n";
        int nxt=cnt;
        m--;
        if(!m) break ;
        cnt++;
        cout<<now<<" "<<cnt<<"\n";
        now=nxt;
        m--;
    }
}

虽然 CF 题加不了 hack,但是无所谓了(


by cmaths @ 2023-12-30 11:32:10

@World_Creater 但是这篇题解不是先合并再插入的吗。应该不会出现你说的情况吧

还是我理解错了


by cmaths @ 2023-12-30 14:30:33

啊这没事了我理解错了 T_T


by cmaths @ 2023-12-30 14:33:26

那如果每次优先访问重儿子是不是就不会出问题了呢,求解


by cmaths @ 2023-12-30 14:55:07

好像是正确的。见 link


by _Kenma_ @ 2024-07-17 10:06:15

按size顺序遍历子节点空间消耗小的离谱,甚至不需要回收节点(?


|