Great question, Own binary search, Explained
\ntime : O(nlogn) space: O(n)\nInspiration from @ye15 post\n\nOwn binary search\n\nclass Solution {\npublic:\n    int binarySearch(vector<int>&presum, int idx, 
\ntime : O(nlogn) space: O(n)\nInspiration from @ye15[ post](https://leetcode.com/problems/ways-to-split-array-into-three-subarrays/discuss/999157/Python3-binary-search-and-2-pointer)\n\n**Own binary search**\n```\nclass Solution {\npublic:\n    int binarySearch(vector<int>&presum, int idx, int sum, bool flag){\n        \n        // just for readability\n        int leftsum, rightsum;\n        if(flag)leftsum = sum;\n        else rightsum = sum;\n        \n        int low = idx, high = presum.size()-1, index = -1;\n        while(low <= high){\n            int mid = low + ((high-low)>>1);\n            int midsum = presum[mid];\n            if(flag){\n                if(leftsum <= midsum){\n                    index = mid;\n                    high = mid-1;\n                }\n                else low = mid+1;\n            }\n            else{\n                if(midsum <= rightsum){\n                    index = mid;\n                    low = mid+1;\n                }\n                else high = mid-1;\n            }\n        }        \n        return index;\n    }\n    int waysToSplit(vector<int>& nums) {\n        int n = nums.size();\n        \n        vector<int>presum(n, nums[0]);\n        for(int i = 1; i < n; ++i) presum[i] = presum[i-1] + nums[i];\n        \n        int res = 0, MOD = 1e9+7;\n        for(int i = 0; i < n; ++i){\n            \n            // first cut at index just after i, and second cut at j where j in [l,r]\n            // Hence, presum[i] <= presum[j] - presum[i] <= presum[n-1] - presum[j]\n            \n            // 1st condition: 2*presum[i] <= presum[j]\n            int l = binarySearch(presum, i+1, 2*presum[i], true); \n            \n            // 2nd condition: 2*presum[j] <= presum[n-1] + presum[i]\n            int r = binarySearch(presum, i+1, (presum[n-1] + presum[i])/2, false); \n            \n            if(l == -1 || r == -1)continue;\n            \n            r = min(r, n-2); // if r >= n-1, then rightsum partition will be empty\n            l = max(i+1, l); // if l <= i, then midsum partition will be empty \n            \n            // r-l+1 indicates total no of partitions possible after fixing i or leftsum\n            res = (res + max(0, r-l+1)) %MOD;            \n        }\n        \n        return res;\n    }\n};\n```\nRuntime: 284 ms (better)\n\n\n**Binary search stl**\n```\n// time : O(nlogn) space: O(n)\nclass Solution {\npublic:\n    int waysToSplit(vector<int>& nums) {\n        int n = nums.size();\n        \n        vector<int>presum(n, nums[0]);\n        for(int i = 1; i < n; ++i) presum[i] = presum[i-1] + nums[i];\n        \n        int res = 0, MOD = 1e9+7;\n        for(int i = 0; i < n; ++i){\n            \n            // first cut at index just after i, and second cut at j where j in [l,r]\n            // Hence, presum[i] <= presum[j] - presum[i] <= presum[n-1] - presum[j]\n            \n            // 1st condition: 2*presum[i] <= presum[j]\n            int l = lower_bound(presum.begin()+i+1, presum.end(), 2*presum[i]) - presum.begin(); \n            \n            // 2nd condition: 2*presum[j] <= presum[n-1] + presum[i]\n            int r = upper_bound(presum.begin()+i+1, presum.begin()+n-1, (presum[n-1] + presum[i])/2) - presum.begin(); \n            \n            r--;\n            \n            // r-l+1 indicates total no of partitions possible after fixing i or leftsum\n            res = (res + max(0, r-l+1)) %MOD;            \n        }\n        \n        return res;\n    }\n};\n```\nRuntime: 436 ms
['Binary Tree', 'C++']