Letscode_sundar's blog

By Letscode_sundar, history, 3 years ago, In English

I was doing this problem and i noticed a strange thing.

In order to calculate sum of the vector elements , I used the accumulate function available in STL

typedef long long ll;
#define int ll
//the sum variable and elements in vector becomes long long type
int sum=0;
sum=accumulate(v.begin(),v.end(),0);

127183042

This basically gives the wrong answer .

But

#define int ll
int sum=0;
sum=accumulate(v.begin(),v.end(),sum);
or
sum=accumulate(v.begin(),v.end(),0LL);

127184393

127184828

gets accepted.

Why is this happening ?

All these days, I thought it is just an initial value that we give to the accumulate function (the last argument), but it is not just an initial value and plays a big role in the outcome of the sum.

I am telling it isn't just a value because

ll sum=10;
sum+=20;

Now it wouldn't matter if 20 is given in LL or not , but here 0 gives WA but 0LL is accepted.

  • Vote: I like it
  • -26
  • Vote: I do not like it

»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by Letscode_sundar (previous revision, new revision, compare).

»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it
sum=accumulate(v.begin(),v.end(),0);

is as the same as

int result = 0;
for (int x : v) result += x;
sum = result;

Which give you overflow, but 0LL and sum isnt because they are long long type

»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it

#define is nothing more than a copy paste instruction to preprocessor, #define int ll just replaces every occurence of int in your code with ll, but these types don't get magically linked and 0 is still a regular 32-bit int.

»
3 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Referring to https://www.cplusplus.com/reference/numeric/accumulate/

The behavior of this function template is equivalent to:

template <class InputIterator, class T>
   T accumulate (InputIterator first, InputIterator last, T init)
{
  while (first!=last) {
    init = init + *first;  // or: init=binary_op(init,*first) for the binary_op version
    ++first;
  }
  return init;
}

Assuming you know how Templates work (if not http://www.cplusplus.com/doc/oldtutorial/templates/),

calling sum=accumulate(v.begin(),v.end(),0);

The template resolves to accumulate(vector<ll>::iterator, vector<ll>::iterator, int)

and calling sum=accumulate(v.begin(),v.end(),0LL); or sum=accumulate(v.begin(),v.end(),sum); [sum is long long because of macro]

it resolves to accumulate(vector<ll>::iterator, vector<ll>::iterator, ll)

This should explain the behavior as the integer will overflow in the first case and the ll will not in the second.