[Python] Top down DP - Clean & Concise - O(N^2)
Idea\n- Convert arr into arrSet to we can check if an element exists in array in O(1).\n- Let dp(root) is number of binary trees which has root with value root 
**Idea**\n- Convert `arr` into `arrSet` to we can check if an element exists in array in `O(1)`.\n- Let `dp(root)` is number of binary trees which has root with value `root` and follow the problem rules.\n- To calculate `dp(root)`\n\t- We try `cand` in `arrSet`:\n\t\t- If `root % cand == 0` and `root // cand` in `arrSet`, then we can form a valid binary tree with values of 2 children nodes are `cand` and `root // cand`, so\n\t\t\t- Number of valid increase by `dp(cand) * dp(root // cand)`\n```python\nclass Solution:\n    def numFactoredBinaryTrees(self, arr: List[int]) -> int:\n        MOD = 10**9+7\n        arrSet = set(arr)\n        \n        @lru_cache(None)\n        def dp(root):\n            ans = 1\n            for cand in arrSet:\n                if root % cand == 0 and (root // cand) in arrSet:\n                    ans += dp(cand) * dp(root // cand)\n                    ans %= MOD\n            return ans\n        \n        return sum(dp(x) for x in arrSet) % MOD\n```\n**Complexity**\n- Time: `O(N^2)`, where `N <= 1000` is number of elements in the array.\n- Space: `O(N)`
[]