bzoj2870

题解:

边分治入门题

当然并查集+维护直径更加简单

就是两棵树二合一直径是两颗树上的4个直径两两组合的最大值

查询路径长度你搞个差分查个lca就好了

点分治并不能做这题

分成多个联通块就gg了(点分治一般做的是有根树,然后询问跟上下顺序有关的那种)

边分治先得做的事情是把树变成二叉树

不然是可以被菊花图卡掉的

变的过程还是比较简单的

注意我们把虚点点权设为原点点权 边权设为0就可以了

void rebuild() {//重新建树
    tot=1;for(RI i=1;i<=n;++i) h[i]=0;
    for(RI i=1;i<=n;++i) {
        int sz=a[i].size();
        if(sz<=2) {
            for(RI j=0;j<sz;++j)
                add(i,a[i][j],(a[i][j]<=kn)),add(a[i][j],i,(a[i][j]<=kn));
        }
        else {
            int o1=++n,o2=++n;v[o1]=v[o2]=v[i];
            add(i,o1,0),add(o1,i,0),add(i,o2,0),add(o2,i,0);
            for(RI j=0;j<sz;++j)
                if(j&1) a[o2].push_back(a[i][j]);
                else a[o1].push_back(a[i][j]);
        }
    }
}

今天并不是很想写明天写吧。。

posted @ 2018-10-29 20:32  尹吴潇  阅读(249)  评论(0编辑  收藏  举报