kmyk-jikka / Jikka

an automated solver for problems of competitive programming
https://kmyk-jikka.github.io/Jikka/playground
Apache License 2.0
152 stars 11 forks source link

外側で取った mod がきちんと伝播してくれない #186

Closed kmyk closed 2 years ago

kmyk commented 2 years ago

Summary / 概要

外側で取った mod がきちんと伝播してくれない。 計算過程でオーバーフローして WA になってしまうので困る。

Steps to reproduce / 再現方法

examples/wip/yukicoder_1649.py

# https://yukicoder.me/problems/no/1649
from typing import *

MOD = 998244353

def solve(N: int, x: List[int], y: List[int]) -> int:
    ans = 0
    for i in range(N - 1):
        for j in range(i + 1, N):
            ans += (abs(x[i] - x[j]) + abs(y[i] - y[j])) ** 2
    return ans % MOD

# generated by oj-template v4.8.0 (https://github.com/online-judge-tools/template-generator)
def main():
    N = int(input())
    x = list(range(N))
    y = list(range(N))
    for i in range(N):
        x[i], y[i] = map(int, input().split())
    ans = solve(N, x, y)
    print(ans)

if __name__ == '__main__':
    main()

environments:

Expected behavior / 期待される挙動

mod を最後でのみ取るのでなくて、計算過程でもちゃんと取ってほしい

Actual behavior / 実際の挙動

// $ stack run -- convert examples/wip/yukicoder_1649.py | clang-format
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <functional>
#include <iostream>
#include <numeric>
#include <string>
#include <tuple>
#include <vector>
#line 3 "jikka/divmod.hpp"
/**
 * @file jikka/divmod.hpp
 * @author Kimiyuki Onaka
 * @copyright Apache License 2.0
 */
#include <cassert>
#include <cstdint>

namespace jikka {

inline int64_t floordiv(int64_t n, int64_t d) {
  assert(d != 0);
  return n / d - ((n ^ d) < 0 && n % d);
}

inline int64_t floormod(int64_t n, int64_t d) {
  assert(d != 0);
  n %= d;
  return (n < 0 ? n + d : n);
}

inline int64_t ceildiv(int64_t n, int64_t d) {
  assert(d != 0);
  return n / d + ((n ^ d) >= 0 && n % d);
}

inline int64_t ceilmod(int64_t n, int64_t d) {
  assert(d != 0);
  return n - ceildiv(n, d) * d;
}

} // namespace jikka

#line 12 "main.cpp"
int64_t solve(int64_t N_981, std::vector<int64_t> x_982,
              std::vector<int64_t> y_983) {
  int64_t x984 = 0;
  for (int32_t x985 = 0; x985 < N_981 - 1; ++x985) {
    for (int32_t x989 = 0; x989 < -x985 + N_981 - 1; ++x989) {
      x984 = x984 +
             std::max<int64_t>(x_982[x985] - x_982[x985 + x989 + 1],
                               -x_982[x985] + x_982[x985 + x989 + 1]) *
                 std::max<int64_t>(x_982[x985] - x_982[x985 + x989 + 1],
                                   -x_982[x985] + x_982[x985 + x989 + 1]) +
             std::max<int64_t>(x_982[x985] - x_982[x985 + x989 + 1],
                               -x_982[x985] + x_982[x985 + x989 + 1]) *
                 std::max<int64_t>(y_983[x985] - y_983[x985 + x989 + 1],
                                   -y_983[x985] + y_983[x985 + x989 + 1]) *
                 2 +
             std::max<int64_t>(y_983[x985] - y_983[x985 + x989 + 1],
                               -y_983[x985] + y_983[x985 + x989 + 1]) *
                 std::max<int64_t>(y_983[x985] - y_983[x985 + x989 + 1],
                                   -y_983[x985] + y_983[x985 + x989 + 1]);
    }
  }
  return jikka::floormod(x984, 998244353);
}
int main() {
  int64_t N_992 = -1;
  std::cin >> N_992;
  std::vector<int64_t> x_993(N_992, -1);
  std::vector<int64_t> y_994(N_992, -1);
  for (int32_t i_995 = 0; i_995 < N_992; ++i_995) {
    std::cin >> x_993[i_995];
    std::cin >> y_994[i_995];
  }
  auto ans_996 = solve(N_992, x_993, y_994);
  std::cout << ans_996 << ' ';
  std::cout << '\n' << ' ';
}