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]); } } }
今天并不是很想写明天写吧。。