Approach
Depth-first search
For Sum of Perfect Square Ancestors, the implementation follows one branch at a time, making it suitable for components, trees, backtracking, or dependency exploration.
- Define the state carried into one recursive or stack frame.
- Mark or choose the current state before exploring children.
- Combine child results or undo the choice when the branch finishes.
Code notes
- 120 lines of Python from the credited upstream file sum-of-perfect-square-ancestors.py.
- The implementation visibly relies on sequence storage, hash lookup.
- No explicit loop blocks detected, together with recursive traversal.
Complexity
Count unique states for graph traversal; for backtracking, count the branching factor and maximum depth.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1234 5import collections6 7 8def linear_sieve_of_eratosthenes(n): 9 primes = []10 spf = [-1]*(n+1) 11 for i in xrange(2, n+1):12 if spf[i] == -1:13 spf[i] = i14 primes.append(i)15 for p in primes:16 if i*p > n or p > spf[i]:17 break18 spf[i*p] = p19 return spf20 21 22MAX_NUMS = 10**523SPF = linear_sieve_of_eratosthenes(MAX_NUMS)24 2526class Solution(object):27 def sumOfAncestors(self, n, edges, nums):28 """29 :type n: int30 :type edges: List[List[int]]31 :type nums: List[int]32 :rtype: int33 """34 def prime_factors(x):35 result = 136 while x != 1:37 if result%SPF[x] == 0:38 result = SPF[x]39 else:40 result *= SPF[x]41 x = SPF[x]42 return result43 44 def iter_dfs():45 result = 046 stk = [(1, (0, -1))]47 while stk:48 step, args = stk.pop()49 if step == 1:50 u, p = args51 x = prime_factors(nums[u])52 result += cnt[x]53 cnt[x] += 154 stk.append((3, (x,)))55 stk.append((2, (u, p, 0)))56 elif step == 2:57 u, p, i = args58 if i == len(adj[u]):59 continue60 stk.append((2, (u, p, i+1)))61 v = adj[u][i]62 if v == p:63 continue64 stk.append((1, (v, u)))65 elif step == 3:66 x = args[0]67 cnt[x] -= 168 return result69 70 adj = [[] for _ in xrange(n)]71 for u, v in edges:72 adj[u].append(v)73 adj[v].append(u)74 cnt = collections.defaultdict(int)75 return iter_dfs()76 77 78798081import collections82 83 8485class Solution2(object):86 def sumOfAncestors(self, n, edges, nums):87 """88 :type n: int89 :type edges: List[List[int]]90 :type nums: List[int]91 :rtype: int92 """93 def prime_factors(x):94 result = 195 while x != 1:96 if result%SPF[x] == 0:97 result = SPF[x]98 else:99 result *= SPF[x]100 x = SPF[x]101 return result102 103 def dfs(u, p):104 x = prime_factors(nums[u])105 result = cnt[x]106 cnt[x] += 1107 for v in adj[u]:108 if v == p:109 continue110 result += dfs(v, u)111 cnt[x] -= 1112 return result113 114 adj = [[] for _ in xrange(n)]115 for u, v in edges:116 adj[u].append(v)117 adj[v].append(u)118 cnt = collections.defaultdict(int)119 return dfs(0, -1)120