0

Link to Problem:- https://www.spoj.com/problems/GSS1

  1. I am using Segment tree.

    Node Information:-

  2. maxSum --> maximum sum of the segment represented by node.

  3. Sum ---> Total Sum of segment. (Although i think it's not needed)
  4. maxPrefixSum ---> maximum prefix sum possible in segment. i.e starting from first element of segment.
  5. maxSuffixSum ---> same as maxPrefixSum but starting from last element of segment.

Calculation of Node Values:-

("res" is new node, "left" and "right" are its left and right childs respectively)
res.Sum = left.Sum + right.Sum;
res.maxSum = max(max(left.maxSum, right.maxSum), left.maxSuffixSum + right.maxPrefixSum);
res.maxSuffixSum = max(left.maxSuffixSum + right.Sum, right.maxSuffixSum);
res.maxPrefixSum = max(left.maxPrefixSum, left.Sum + right.maxPrefixSum);

CODE

#include<bits/stdc++.h>
using namespace std;

#define int long long int

class node
{
public:
    int Sum, maxSuffixSum, maxPrefixSum, maxSum;
    node()
    {
        Sum = maxSuffixSum = maxPrefixSum = maxSum = 0;
    }
};

node node_value(node left, node right)
{
    node res;
    res.Sum = left.Sum + right.Sum;
    res.maxSum = max(max(left.maxSum, right.maxSum), left.maxSuffixSum + right.maxPrefixSum);
    res.maxSuffixSum = max(left.maxSuffixSum + right.Sum, right.maxSuffixSum);
    res.maxPrefixSum = max(left.maxPrefixSum, left.Sum + right.maxPrefixSum);
    return res;
}

void makeSegmentTree(vector<int> arr, vector<node> &tree, int idx, int start, int finish)
{
    if(finish == start)
    {
        tree[idx].Sum = tree[idx].maxPrefixSum = tree[idx].maxSuffixSum = tree[idx].maxSum = arr[start];
        return;
    }

    int mid = start + (finish - start)/2;
    makeSegmentTree(arr, tree, 2*idx, start, mid);
    makeSegmentTree(arr, tree, 2*idx+1, mid+1, finish);
    tree[idx] = node_value(tree[2*idx], tree[2*idx + 1]);
}

node queryTree(vector<node> &tree, int idx, int start, int finish, int left, int right)
{
    if(start >= left && finish <= right)
    {
        return tree[idx];
    }
    else
    {
        int mid = start + (finish - start)/2;
        if(start <= left && right <= mid)
        {
            return queryTree(tree, 2*idx, start, mid, left, right);
        }
        else if(left > mid && right <= finish)
        {
            return queryTree(tree, 2*idx+1, mid+1, finish, left, right);
        }
        else
        {
            node ans1 = queryTree(tree, 2*idx, start, mid, left, mid);
            node ans2 = queryTree(tree, 2*idx+1, mid+1, finish, mid+1, right);
            return node_value(ans1, ans2);
        }
    }
}
int32_t main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    vector<int> arr(n+1, 0);
    for(int i=1;i<n+1;i++)
    {
        cin>>arr[i];
    }


    vector< node > tree(4*n);
    makeSegmentTree(arr, tree, 1, 1, n);

    int q;

    cin>>q;
    while(q--)
    {
        int x, y;
        cin>>x>>y;
        cout<<queryTree(tree, 1, 1, n, x, y).maxSum<<endl;
    }
    return 0;
}

  • 2
    Copying 50000 vector elements 100000 times probably takes too long. – molbdnilo Jan 28 '20 at 09:27
  • 1
    Note that `#define int long long int` causes undefined behaviour. It's not a very clever way to save keystrokes. – molbdnilo Jan 28 '20 at 09:29
  • @molbdnilo Thank you for replying :) I would love to know some clever ways to save such keystrokes –  Jan 29 '20 at 22:44
  • 1
    You have proper type aliases, and lots of names that are not already in use to choose from. For instance,`using T = long long int;` would let you produce bugs even faster. – molbdnilo Jan 30 '20 at 07:03
  • TLE = Too Long Execution? – anatolyg Feb 16 '20 at 08:38

0 Answers0