This problem is a root tree point division + burn Brain of the tolerance + magical chunking
Because it is the rule 1 is the root, also requires LCA, so we can not be like in a tree without a random wave, we must specify the father, and for special discussion
Because the GCD is not good, so we use the capacity of the conversion, to find X is the number of gcd factor, so that you can casually statistics, personal feel that the code is better than the puzzle to understand.
And because all the children of the center of gravity, and the father of the center of gravity, so in this branch of the father along the center of gravity, this time the center of gravity of the child tree to the center of gravity of the father's distance is changed, so we use the magic of the Block Dafa, classification discussion, $<=\sqrt{n}$ use array to record the answer, Convenient to use later when the statistics, $>\sqrt{n}$ when the direct violence statistics, because at this time the complexity of statistics is not high. This makes the time complexity of the airborne time complexity of $o (N\sqrt{n}) $. Personal feeling is too vague, everything is not as straightforward as looking at code clarity, or to help understand the code of 233
The details of this problem are too many, kneeling 1 days and a half finally AC clam clam Clams
This problem I first film 鏼 ye Code, because a variety of pointers do not understand Ah, but learned the non-recursive center of gravity of the new posture, Infinity film orz!!! Sdoi is to have a variety of non-recursive abilities
Then I film the shallwe of the solution, learned the method of the statistics, Infinity Film Ah!!! Clever special and two pointers to move so that the statistics are not heavy, it is amazing!!!
Finally, charge taught me the pressure of Dafa, the various loops used to judge the "Min", "+" in advance to calculate, the constant small to you can not imagine!!!
In the end, my code was RANK1 in Uoj time efficiency.
Continue to be complacent in ...........
Give me the code:
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm>using namespace std; typedef long LONG ll;const int N = 200003;void read (int &k) {k = 0; int fh = 1; char c = GetChar (); for (; c < ' 0 ' | | C > ' 9 '; c = GetChar ()) if (c = = '-') FH = -1;for (; c >= ' 0 ' && C <= ' 9 '; c = GetChar ()) K = (k << 1) + (k <&L T 3) + C-' 0 '; k = k * FH;} BOOL vis[n];struct Node {int NXT, to;} E[n];int Qu[n], ct[n], N, M, Fa[n], DE, deep[n], cnt = 0, point[n], root, sz[n], Boo[n];ll t[503][503], cn[n], sct[n], SCN [N], ans2[n], s[n];void ins (int x, int y) {e[++cnt].nxt = point[x]; e[cnt].to = y; POINT[X] = cnt;} void findrt (int x) {int p = 0, q = 0; Qu[++q] = X;while (P! = q) {int u = qu[++p];boo[u] = Sz[u] = 1;for (int tmp = Point[u ]; tmp TMP = E[TMP].NXT) if (!vis[e[tmp].to]) qu[++q] = e[tmp].to;} for (int i = q; i; i) {if (Boo[qu[i]] && Sz[qu[i]] * 2 >= q) {root = Qu[i]; return;} Sz[fa[qu[i]] + = Sz[qu[i]];if (Sz[qu[i]] * 2 >= Q) boo[fa[Qu[i]] = 0;}} Non-recursive to find the center of gravity!!! The national team Rank3 's 鏼 ye Orz to sdoiers bring benefits void BFS (int x) {deep[x] = 1;int p = 0, q = 0; Qu[++q] = X;while (P! = q) {int u = qu[++p]; ++ct [Deep[u]];for (int tmp = point[u]; tmp; TMP = E[TMP].NXT) if (!vis[e[tmp].to]) deep[e[tmp].to] = Deep[u] + 1, qu[++q] = e[tmp ].to;} de = Deep[qu[q]];} void Q (int x) {Vis[x] = 1;int up = 0, upp = 0;for (int tmp = point[x]; tmp = E[TMP].NXT) if (!vis[e[tmp].to]) {BFS (E[tm P].TO); up = max (up, de); for (int i = 1; I <= de; ++i) for (int j = i; J <= de; J + = i) cn[i] + = ct[j];for (int i = 1; I & Lt;= de; ++i) {Ans2[i] + = ct[i];sct[i] + = Ct[i]; S[i] + = scn[i] * Cn[i];scn[i] + cn[i];ct[i] = Cn[i] = 0;}} SCT[0] = 1;int Step = 0, son = x, line, to;for (int i = fa[x];!vis[i] && i; son = i, i = Fa[i]) {++step; to = 0;fo R (int tmp = point[i]; tmp; TMP = E[TMP].NXT) if (!vis[e[tmp].to] && e[tmp].to! = son) BFS (e[tmp].to), to = max (To, D e);d e = To;upp = Max (upp, de); for (int. j = 1; j <= de; ++j) for (int k = j; k <= de; k + + j) Cn[j] + = Ct[k];line = min (DE, M); for (int j = 1; J <= Line; ++j) {to = step% j;if (t[j][to] = = 1) {T[j][to] = 0;for (int k = (j-to)% J K <= up; K + = j) T[j][to] + = Sct[k];} S[J] + = t[j][to] * cn[j];} for (int j = m + 1, j <= de; ++j) for (int k = (j-step% j)% J, K <= up; k + + j) S[j] + = sct[k] * cn[j];for (int j = 1 ; J <= de; ++J) Ct[j] = cn[j] = 0;++ans2[step];} The following is an int L = 1, R = 0, tot = step + up;ll now = 0;for (int i = 2; I <= tot; ++i) {if (R + 1 < i) Shallwe + + SCT [++r];if (L + Step < i) now-= Sct[l++];ans2[i] + now;} line = min (M, upp) above shallwe, for (int i = 1; i <= lines; ++i) for (int j = 0; J < i; ++j) t[i][j] = -1;for (int i = 0; I <= up; ++i) Sct[i] = Scn[i] = 0;if (son! = x) {findrt (son); Q (root);} for (int tmp = POINT[X]; TMP, TMP = E[TMP].NXT) if (!vis[e[tmp].to]) {FINDRT (e[tmp].to); Q (root);}} ll Ans[n];int Main () {read (n); m = (sqrt (n)); for (int i = 2; I <= N; ++i) {read (fa[i]); Ins (fa[i], i);} memset (T,-1, sizeof (t)); FINDRT (1); Q (root); for (int i = n-1; I i) for (int j = i + i; j < n; j + = i) s[i]-= s[j];for (int i = 1; i < n; ++i) printf ("%lld\n", S[i] + ans2[i]); return 0;}
There's nothing to be afraid of, I think that's really good.
"UR #2" tree on GCD