C# Solution | Time: O(n*k), Memory: O(n) | Easy to understand, Dynamic programming, Dictionary
C#\npublic class Solution {\n    private static int _mod = 1000000007;\n    public int NumFactoredBinaryTrees(int[] arr) {\n        Dictionary<int, long> memo =
```C#\npublic class Solution {\n    private static int _mod = 1000000007;\n    public int NumFactoredBinaryTrees(int[] arr) {\n        Dictionary<int, long> memo = new ();\n        \n        HashSet<int> nums = new (arr);\n        int ans = 0;\n        for (int i = 0; i < arr.Length; i++)\n            ans = (ans + (int)Solve(arr[i])) % _mod;\n        \n        return ans;\n        \n        long Solve(int num) {\n            if (memo.TryGetValue(num, out var memoizedResult)) return memoizedResult;\n            \n            long count = 0;\n            if (nums.Contains(num)) {\n                count++;\n\n                int sqrt = (int)Math.Sqrt(num);\n                for (int i = 2; i <= sqrt; i++) {\n                    if (num % i == 0) {\n                        int t = num / i;\n                        long p = Solve(i) * Solve(t) % _mod;\n                        count = (count + (int)p) % _mod;\n                        if (i != t) count = (count + (int)p) % _mod;\n                    }\n                }\n            }\n            \n            memo[num] = count;\n            return count;\n        }\n    }\n}\n```
['Dynamic Programming']