-2

The nth term of the series is f(n).

      f(n) = 1, when n=1
      f(n)= ((n-1)*(8*(n–2)* 2+ 20)+4) , when n>1
      P(n)=f(1)+f(2)+.....f(n)
      1<=n<=10^9

for a given n we have to find P(n) modulo 10^9+7.

I solved the equation and finally getting the answer as P(n)=(16n^3-18n^2+14n-12)/3

Problem comes when I implemented it in c++.

Given below the code tell me whats wrong with it and how to resolve it?

#include<stdio.h>

#define c 1000000007

int main()
{
long long int t,n,sum;
scanf("%lld",&t);
while(t--)
{
    sum=0;
    scanf("%lld",&n);
    if(n==1)
        printf("1\n");
    else
    {
        sum=(((16*(((((n%c)*(n%c))%c)*(n%c))%c)%c)+14*(n%c))%c-(18*(((n%c)*(n%c))%c)%c+12)%c)/3;
        sum++;
        printf("%lld\n",sum);
    }
}
return 0;
}
Vistanza
  • 65
  • 10

1 Answers1

0

There are multiple issues in your code.

Problem 1:
An expression like long long b = ((a%c)*(a%c))%c; with a and b being long long
and c just a "plain number", ie. int, is still subject to int overflow, without
using the full capabilities of long long. The reason is the result of modulo:

long long = ((long long % int) * (long long % int)) % int;
long long = (int * int) % int;
long long = int % int; //overflow here
long long = int;
long long = long long; //expanding too late
//finished

As an example to check (http://ideone.com/kIyM7K):

#include <iostream>
using namespace std;

int main() {
    int i = 1000000;
    long long ll = 1000000;
    cout<< ((999999%i)*(999999%i)*(999999%i)) << endl;
    cout<< ((999999%ll)*(999999%ll)*(999999%ll)) << endl;
    return 0;
}

In your code, 1000000007 is not a long long ...
Use 1000000007ULL to treat is as unsigned long long

Problem 2:
You´re using (or at least "used", before the edits) %lld in printf and scanf
for unsigned long long, which is %llu. %lld would be a signed long long

Problem 3:
P(n) purely mathematical and without modulo is positive for every natural number n>=1.
But P(0) is negative, and more important: The four parts of your equation modul´t
and the added/subtracted together could result in a negative number, which is congruent
to the positive expected result, but C doesn´t know that.
So, use signed instead of unsigned, and after the whole calculation, check
if the result is <0 and add c to it to make it >0

Problem 4:
A problem with parenthesis and operator precedence somewhere in your long formula.
A working example, but without the loops and input:

#include<stdio.h>
int main()
{
    signed long long n, res, c;
    n = 2456ULL;
    c = 1000000007ULL;
    signed long long part1 = (16*(((n%c)*(n%c)%c)*(n%c)%c))%c;
    signed long long part2 = (18*((n%c)*(n%c)%c))%c;
    signed long long part3 = (14*(n%c))%c;
    res = ((part1 - part2 + part3 - 12)%c)/3 + 1;
    printf("%lld\n", res);
    return 0;
}

Not a problem:
You don´t need a special check for n=1, because the
whole calculation will result in 1 anyways.

deviantfan
  • 11,268
  • 3
  • 32
  • 49