2020.02.03日常总结

P3478   [POI2008]STAStation\color{green}{洛谷P3478\ \ \ [POI2008]STA-Station}

\color{blue}{【题意】:} 给您一棵有NN个点的无根树,求一个点,以这个点为根的树时,所有点的深度之和最大。1N1×1061 \leq N \leq 1 \times 10^6

\color{blue}{【思路】:} 首先,我们求出以11为根(当然,以其它点为根也可以,毕竟是无根树嘛),求出此时所有点的深度和S1S_1和子树大小SizexSize_x

考虑从一个点uu向下移动到它的儿子vv时,总答案有什么变化。很明显,vv的子树内的节点的深度全部1-1,而其它的点的深度+1+1,即:

Sv=SuSizev+(NSizev)=Su+N2×SizevS_v=S_u-Size_v+(N-Size_v)=S_u+N-2 \times Size_v

有了它,我们就可以O(N)O(N)处理啦——

\color{blue}{【代码】:}
2020.02.03日常总结
2020.02.03日常总结
\color{blue}{【语法点透析】:}

  • add(read(),read()):这句话根本不像我们想象的那么“单纯”,它是反过来的。什么意思?即输入1 2,实际上运行的是add(2,1),而不是add(1,2)
  • e[N<<1]:为什么要两倍空间?不是已经确定了根为11吗?其实,哪怕我们知道根是什么,我们仍然不能在输入时就确定这棵树的形态,所以我们仍然不知道谁是父亲谁是儿子,所以还是得两倍空间。