C++ | 3 pointer O(n) | Binary Search O(n*Logn)
create prefix sum array\nleft (0,i)\nmiddle(i+1,r)\nright (r+1,n-1)\nchoose only that  range in middle that satify both middle<=right and left<=middle\n\nfindin
create prefix sum array\nleft (0,i)\nmiddle(i+1,r)\nright (r+1,n-1)\nchoose only that  range in middle that satify both middle<=right and left<=middle\n\nfinding pointers via binarySearch\n\n    int waysToSplit(vector<int>& nums) {\n        #define MOD 1000000007\n        int n=nums.size();\n        for(int i=1;i<n;i++)\n            nums[i]+=nums[i-1];\n        int ans=0;\n        int beta,alpha;\n        for(int i=0;i<n-2;i++)\n        {\n            int left=nums[i];\n            int low=i+1;\n            int high=n-2;\n    \n            while(high-low>1)\n            {\n                int mid=(high+low)>>1;\n                int right=nums[n-1]-nums[mid];\n                int middle=nums[mid]-left;\n                if(right>=middle) low=mid;\n                else high=mid;\n            }\n            if(nums[n-1]+left>=2*nums[high]) beta=high;\n            else if(nums[n-1]+left>=2*nums[low]) beta=low;\n            else beta=-1;\n            if(beta>=0)    \n            {\n                low=i+1;\n                high=beta;\n                while(high-low>1)\n                {\n                 int mid=(high+low)>>1;\n                 int middle=nums[mid]-left;\n                 if(middle>=left) high=mid;\n                 else low=mid;\n                }\n                if(nums[low]>=2*left) alpha=low;\n                else if(nums[high]>=2*left) alpha=high;\n                else alpha=-1;\n            }\n            if(beta>=0 && alpha>=0)\n            {   \n                ans+=(beta-alpha+1)%MOD;\n                ans%=MOD;\n            }\n            //cout<<i<<" alpha:"<<alpha<<" beta:"<<beta<<endl;\n        }\n        return ans;\n    }\n\nnotice:\nfor pointer alpha middle>=left so if left increases middle will increase via increasing alpha\nfor pointer beta middle<=right if left increases middle will decrease ,so to increase middle for fixed left beta needs to be increased. therefore in each left update new aplha and beta will be greate than equal to prev values. Hence problems can be reduced to O(n)\n\n    int waysToSplit(vector<int>& nums) {\n        #define MOD 1000000007\n        int n=nums.size();\n        for(int i=1;i<n;i++)\n            nums[i]+=nums[i-1];\n        int ans=0;\n        int alpha=1;\n        int beta=1;\n        for(int i=0;i<n-2;i++)\n        {\n            int left=nums[i];\n            alpha=max(alpha,i+1);\n            while(alpha<n-1)\n            {\n               int middle=nums[alpha]-left;\n               if(middle<left)  alpha++;\n               else break;\n            }\n            beta=max(alpha,beta);\n            while(beta<n-1)\n            {\n               int middle=nums[beta]-left;\n               int right=nums[n-1]-nums[beta];\n               if(middle<=right) beta++;\n               else break;\n            }\n            if(nums[n-1]-nums[beta]<nums[beta]-left || beta==n-1) beta--;\n            if(beta<n-1 && alpha<n-1 && beta>=alpha && nums[alpha]>=2*left && nums[n-1]+left>=2*nums[beta] )\n            {   \n                ans+=(beta-alpha+1)%MOD;\n                ans%=MOD;\n            }\n            //cout<<"i: "<<i<<" alpha:"<<alpha<<" beta:"<<beta<<endl;\n        }\n        return ans;\n    }
['Binary Search']