学习了树剖之后发现这真是一个打起来非常爽的算法。
可以流畅的敲下dfs1,dfs2,build然后再加些奇奇怪怪的东西。
不过还是有一些总结
比如说
1.线段树维护的是新序号而非dfs序。
时刻记住涉及到线段树操作都要加一个id[…]。
2.有初值的题可以在dfs2中的id[u]=++cnt后加入一个数组pre[cnt]=u;这样在build叶子节点时可以直接t[u].(维护值)=val[pre[l]]。
3.涉及到子树操作可以使用size数组。可以直接在线段树上进行id[u]到id[u]+size[u]-1的区间操作。
4.对于边权的题往往把边权放在儿子结点上转换为点权维护。所以树剖修改的最后一步往往为id[a]+1到id[b],这样可以有效地不影响LCA的维护值。
5.线段树如果涉及到更改与加减乘除标记同时下传,一定记住更改至高无上。意思是说在pushdown的时候:t[u*2].addtag=t[u*2+1].addtag=0;可以直接清零甩掉。
6.如果涉及到边权且要求修改第k条边的值,那映射到线段树序号可以视为id[x],其中x=dep[to[k*2]]<dep[to[k*2-1]]?to[k*2-1]:to[k*2];一定记住反向边的存在使得k要*2或者*2-1。
其它东西可以因题而异地输出了。大致来说只要做好上面这些并且不要在树剖查询的时候搞忘更新a和top[a]而RE,其它都不算太难。这是一个比较简单的算法。
但总有毒瘤的出题人。