2014-10-26 3 views
-2

n-й член ряда - 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 

для данного n мы должны найти P (n) по модулю 10^9 + 7.

Я решил уравнение и, наконец, получить ответ, как Р (п) = (16N^3-18n^2 + 14n-12)/3

Проблема возникает, когда я реализовал его в C++.

Учитывая приведенный ниже код, скажите мне, что с ним не так, и как его решить?

#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; 
} 
+0

Если вы изменили свои включения и пространство имен, это C, а не C++. Такая смесь будет получать downvotes здесь, вы должны изменить ее. И если у вас уже есть простое уравнение, почему бы не использовать его? Вместо того, что много по модулю ... – deviantfan

+0

И я не вижу суммы всех частей в вашей программе ... но что вы там делаете? Две переменные scanf'ed - первая странная вещь. (Редактирование теперь не поможет, потому что, по-видимому, вы не знаете, что делаете) – deviantfan

+0

Значение n может быть до 10^9, что вызовет переполнение. – Vistanza

ответ

0

В коде содержится несколько вопросов.

Задача 1:
Выражение как long long b = ((a%c)*(a%c))%c; с и б быть long long
и С просто «обычный номер», то есть. int, по-прежнему подвержен переполнению int, без
с использованием всех возможностей long long. Причиной является результатом по модулю:

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 

В качестве примера для проверки (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; 
} 

В коде 1000000007 не long long ...
Использование 1000000007ULL для лечения является а unsigned long long

Проблема 2:
You're использованием (или по крайней мере, «используется», до внесения изменений) %lld в printf и scanf
для unsigned long long, то есть %llu. %lld бы подписанная long long

Проблема 3:
P (N) чисто математические и без по модулю положителен для любого натурального числа п> = 1.
Но Р (0) является отрицательным, и что более важно: Четыре частью вашего уравнения modul't
и добавленным/вычитается вместе может привести к отрицательному числу, которое конгруэнтно
к положительному ожидаемому результату, но C этого не знает.
Таким образом, использование signed вместо unsigned, и после всего расчета, проверьте
если результат <0 и добавьте гр к нему, чтобы сделать его >0

Задача 4:
Проблема с скобкой и оператором приоритет где-то в вашей длинной формуле.
рабочий пример, но без петель и ввода:

#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; 
} 

не проблема:
вам не нужен специальный чек для п = 1, потому что весь расчет
приведет 1 в любом случае.