Решаю задачу Сумма квадратов с e-olimp. Что не так в этом куске кода? Подозреваю что ошибка во взятии по модулю.
cin >> n >> m;
if (n < 0 && m < 0) {
n = abs(n); m = abs(m);
}
if (n > m) swap(n, m);
long long sum1 = 0, sum2 = 0, gr, GR;
gr = abs(n);
if (n > 0)
--gr;
sum1 = ((MOD + (gr * (gr + 1) * (2 * gr + 1) / 6) % MOD) % MOD);
GR = abs(m);
sum2 = ((MOD + (GR * (GR + 1) * (2 * GR + 1) / 6) % MOD) % MOD);
ll ans;
if (n > 0)
ans = (MOD + (sum2 - sum1) % MOD) % MOD;
else
ans = (MOD + (sum2 + sum1) % MOD) % MOD;
assert(ans >= 0);
cout << ans;
cout << '\n';
UPD: Прошу прощения за кривую разметку
При больших значениях
gr
происходит переполнениеint64
. Надо модули более узко расставить.Ещё некорректно делить по модулю. Надо умножать на делитель возведённый в степень
MOD - 2
.Последнее предложение верно, только если MOD простое число. Более правильно сказать, что следует домножать на обратный(по модулю MOD) к делителю(к шестёрке) элемент. Если MOD не взаимно прост с 6, то нужно извращаться: например для каждого числа помнить сколько раз в его разложении на простые множители присутсвует 2 и 3, и остаток от деления на MOD / НОД(MOD, 6).
Можно же проще, если я не ошибаюсь. Хотя бы одно из этих чисел(gr,gr+1,2*gr+1) будет делиться на 2. Аналогичное утверждение верно для 3. И можно соответствующие числа изначально(до перемножения) поделить на 2(3). А дальше просто перемножить по модулю.