long long queryST(STNode *root, int s, int e){
     if(!root || s > e)
         return -1;
     if(root->start == s && root->end == e)
         return root->sum;
     int mid = root->start + (root->end - root->start)/2;
     long l = queryST(root->left, max(root->start, s), min(mid, e));
     long r = queryST(root->right, max(mid + 1, s), min(e, root->end));
     if(s > mid)
         return r;
     if(e <= mid)
         return l;
     return l + r;
 }
Real DistTriangle3Rectangle3<Real>::GetSquared ()
{
    // Compare edges of triangle to the interior of rectangle.
    Real sqrDist = Math<Real>::MAX_REAL, sqrDistTmp;
    Segment3<Real> edge;
    int i0, i1;
    for (i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
    {
        edge.Center = ((Real)0.5)*(mTriangle->V[i0] +
            mTriangle->V[i1]);
        edge.Direction = mTriangle->V[i1] - mTriangle->V[i0];
        edge.Extent = ((Real)0.5)*edge.Direction.Normalize();
        edge.ComputeEndPoints();

        DistSegment3Rectangle3<Real> querySR(edge, *mRectangle);
        sqrDistTmp = querySR.GetSquared();
        if (sqrDistTmp < sqrDist)
        {
            // The triangle point is reported in mClosestPoint0 and the
            // rectangle point is reported in mClosestPoint1.  The querySR
            // calculator is for triangleEdge-rectangle, so GetClosestPoint0()
            // and GetClosestPoint1() must be called as listed next.
            mClosestPoint0 = querySR.GetClosestPoint0();
            mClosestPoint1 = querySR.GetClosestPoint1();
            sqrDist = sqrDistTmp;
        }
    }

    // Compare edges of rectangle to the interior of triangle.
    for (i1 = 0; i1 < 2; ++i1)
    {
        for (i0 = -1; i0 <= 1; i0 += 2)
        {
            edge.Center = mRectangle->Center +
                (i0*mRectangle->Extent[1-i1]) *
                mRectangle->Axis[1-i1];
            edge.Direction = mRectangle->Axis[i1];
            edge.Extent = mRectangle->Extent[i1];
            edge.ComputeEndPoints();

            DistSegment3Triangle3<Real> queryST(edge, *mTriangle);
            sqrDistTmp = queryST.GetSquared();
            if (sqrDistTmp < sqrDist)
            {
                // The triangle point is reported in mClosestPoint0 and the
                // rectangle point is reported in mClosestPoint1.  The queryST
                // calculator is for rectangleEdge-triangle, so
                // GetClosestPoint1() and GetClosestPoint0() must be called as
                // listed next.
                mClosestPoint0 = queryST.GetClosestPoint1();
                mClosestPoint1 = queryST.GetClosestPoint0();
                sqrDist = sqrDistTmp;
            }
        }
    }

    return sqrDist;
}
 /**
  *@param A, queries: Given an integer array and an query list
  *@return: The result list
  */
 vector<long long> intervalSum(vector<int> &A, vector<Interval> &queries) {
     // write your code here
     STNode* root = buildST(A, 0, (int)A.size() - 1);
     vector<long long> res;
     if(!root)
         return res;
     for(int i = 0; i < (int)queries.size(); i++){
         res.push_back(queryST(root, queries[i].start, queries[i].end));	
     }
     return res;
 }
Real DistTriangle3Triangle3<Real>::GetSquared ()
{
	// Compare edges of triangle0 to the interior of triangle1.
	Real sqrDist = Math<Real>::MAX_REAL, sqrDistTmp;
	Segment3<Real> edge;
	Real ratio;
	int i0, i1;
	for (i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
	{
		edge.Center = ((Real)0.5)*(mTriangle0->V[i0] +
		                           mTriangle0->V[i1]);
		edge.Direction = mTriangle0->V[i1] - mTriangle0->V[i0];
		edge.Extent = ((Real)0.5)*edge.Direction.Normalize();
		edge.ComputeEndPoints();

		DistSegment3Triangle3<Real> queryST(edge, *mTriangle1);
		sqrDistTmp = queryST.GetSquared();
		if (sqrDistTmp < sqrDist)
		{
			mClosestPoint0 = queryST.GetClosestPoint0();
			mClosestPoint1 = queryST.GetClosestPoint1();
			sqrDist = sqrDistTmp;

			ratio = queryST.GetSegmentParameter()/edge.Extent;
			mTriangleBary0[i0] = ((Real)0.5)*((Real)1 - ratio);
			mTriangleBary0[i1] = (Real)1 - mTriangleBary0[i0];
			mTriangleBary0[3-i0-i1] = (Real)0;
			mTriangleBary1[0] = queryST.GetTriangleBary(0);
			mTriangleBary1[1] = queryST.GetTriangleBary(1);
			mTriangleBary1[2] = queryST.GetTriangleBary(2);

			if (sqrDist <= Math<Real>::ZERO_TOLERANCE)
			{
				return (Real)0;
			}
		}
	}

	// Compare edges of triangle1 to the interior of triangle0.
	for (i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
	{
		edge.Center = ((Real)0.5)*(mTriangle1->V[i0] +
		                           mTriangle1->V[i1]);
		edge.Direction = mTriangle1->V[i1] - mTriangle1->V[i0];
		edge.Extent = ((Real)0.5)*edge.Direction.Normalize();
		edge.ComputeEndPoints();

		DistSegment3Triangle3<Real> queryST(edge, *mTriangle0);
		sqrDistTmp = queryST.GetSquared();
		if (sqrDistTmp < sqrDist)
		{
			mClosestPoint0 = queryST.GetClosestPoint0();
			mClosestPoint1 = queryST.GetClosestPoint1();
			sqrDist = sqrDistTmp;

			ratio = queryST.GetSegmentParameter()/edge.Extent;
			mTriangleBary1[i0] = ((Real)0.5)*((Real)1 - ratio);
			mTriangleBary1[i1] = (Real)1 - mTriangleBary1[i0];
			mTriangleBary1[3-i0-i1] = (Real)0;
			mTriangleBary0[0] = queryST.GetTriangleBary(0);
			mTriangleBary0[1] = queryST.GetTriangleBary(1);
			mTriangleBary0[2] = queryST.GetTriangleBary(2);

			if (sqrDist <= Math<Real>::ZERO_TOLERANCE)
			{
				return (Real)0;
			}
		}
	}

	return sqrDist;
}