結果

問題 No.1201 お菓子配り-4
ユーザー HaarHaar
提出日時 2020-08-28 22:24:56
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 5,275 bytes
コンパイル時間 2,237 ms
コンパイル使用メモリ 198,088 KB
実行使用メモリ 10,400 KB
最終ジャッジ日時 2024-04-26 13:23:31
合計ジャッジ時間 33,886 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 89 ms
6,816 KB
testcase_01 AC 1,187 ms
6,944 KB
testcase_02 AC 1,714 ms
6,944 KB
testcase_03 AC 848 ms
6,940 KB
testcase_04 AC 405 ms
6,940 KB
testcase_05 AC 1,011 ms
6,944 KB
testcase_06 AC 154 ms
6,944 KB
testcase_07 AC 455 ms
6,940 KB
testcase_08 AC 1,271 ms
6,944 KB
testcase_09 AC 935 ms
6,940 KB
testcase_10 AC 8 ms
6,940 KB
testcase_11 AC 242 ms
6,940 KB
testcase_12 AC 1,953 ms
6,944 KB
testcase_13 AC 54 ms
6,944 KB
testcase_14 AC 27 ms
6,948 KB
testcase_15 AC 1,539 ms
6,940 KB
testcase_16 AC 466 ms
6,944 KB
testcase_17 AC 603 ms
6,940 KB
testcase_18 AC 99 ms
6,944 KB
testcase_19 AC 93 ms
6,940 KB
testcase_20 AC 2 ms
6,944 KB
testcase_21 AC 2 ms
6,940 KB
testcase_22 AC 2 ms
6,940 KB
testcase_23 AC 2 ms
6,940 KB
testcase_24 AC 2 ms
6,944 KB
testcase_25 AC 2 ms
6,944 KB
testcase_26 AC 2 ms
6,944 KB
testcase_27 AC 2 ms
6,940 KB
testcase_28 AC 2 ms
6,940 KB
testcase_29 AC 2 ms
6,944 KB
testcase_30 AC 2,467 ms
6,940 KB
testcase_31 AC 2,472 ms
6,944 KB
testcase_32 AC 2,471 ms
6,944 KB
testcase_33 AC 2,455 ms
6,944 KB
testcase_34 AC 2,430 ms
6,940 KB
testcase_35 TLE -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

#ifdef DEBUG
#include <Mylib/Debug/debug.cpp>
#else
#define dump(...) ((void)0)
#endif

template <typename T, typename U>
bool chmin(T &a, const U &b){
  return (a > b ? a = b, true : false);
}

template <typename T, typename U>
bool chmax(T &a, const U &b){
  return (a < b ? a = b, true : false);
}

template <typename T, size_t N, typename U>
void fill_array(T (&a)[N], const U &v){
  std::fill((U*)a, (U*)(a + N), v);
}

template <typename T>
auto make_vector(int n, int m, const T &value){
  return std::vector<std::vector<T>>(n, std::vector<T>(m, value));
}

template <typename T>
std::ostream& operator<<(std::ostream &s, const std::vector<T> &a){
  for(auto it = a.begin(); it != a.end(); ++it){
    if(it != a.begin()) s << " ";
    s << *it;
  }
  return s;
}

template <typename T>
std::istream& operator>>(std::istream &s, std::vector<T> &a){
  for(auto &x : a) s >> x;
  return s;
}

/**
 * @title Montgomery multiplication
 * @docs montgomery.md
 */
template <int64_t M_>
struct Montgomery{
  constexpr static int64_t MOD = M_;
  constexpr static int b = 64 - __builtin_clzll(MOD);
  constexpr static int64_t R = 1LL << b;
  constexpr static int64_t R2 = (R % MOD) * (R % MOD) % MOD;

  constexpr static int64_t mask = R - 1; 

  constexpr static int64_t init(){
    int64_t ret = 0, r = R, i = 1, t = 0;
    while(r > 1){
      if(t % 2 == 0) t += MOD, ret += i;
      t >>= 1, r >>= 1, i <<= 1;
    }
    return ret;
  }

  constexpr static int64_t m = init();

  static_assert(R > MOD, "R > MOD");
  static_assert((R & (R - 1)) == 0, "R must be power of 2");

  static int64_t reduce(int64_t T){
    int64_t ret = ((((T & mask) * m) & mask) * MOD + T) >> b;
    if(ret >= MOD) ret -= MOD;
    return ret;
  }

  int64_t val;

  Montgomery(): val(0){}
  Montgomery(int64_t a){
    if(a < 0){
      if(a < -MOD) a = a % MOD + MOD;
      else a += MOD;
    }else if(a >= MOD){
      if(a < 2 * MOD) a -= MOD;
      else a %= MOD;
    }
    
    val = reduce(a * R2);
  }
  Montgomery(const Montgomery &that): val(that.val){}

  auto& operator+=(const Montgomery &that){
    val += that.val;
    if(val >= MOD) val -= MOD;
    return *this;
  }

  auto& operator-=(const Montgomery &that){
    val -= that.val;
    if(val < 0) val += MOD;
    return *this;
  }

  auto& operator*=(const Montgomery &that){
    val = reduce(val * that.val);
    return *this;
  }

  auto& operator/=(const Montgomery &that){
    *this *= that.inv();
    return *this;
  }

  auto operator-() const {
    Montgomery ret(0);
    ret -= *this;
    return ret;
  }

  auto operator+(const Montgomery &that) const {auto ret = *this; return ret += that;}
  auto operator-(const Montgomery &that) const {auto ret = *this; return ret -= that;}
  auto operator*(const Montgomery &that) const {auto ret = *this; return ret *= that;}
  auto operator/(const Montgomery &that) const {auto ret = *this; return ret /= that;}
  
  auto power(int64_t p) const {
    Montgomery ret = 1, e = *this;

    while(p > 0){
      if(p & 1) ret *= e;
      e *= e;
      p >>= 1;
    }

    return ret;
  }

  static auto power(int64_t n, int64_t p){return Montgomery(n).power(p);}

  auto inv() const {return power(MOD - 2);}
  static auto inv(int64_t n){return Montgomery(n).inv();}
  
  friend auto operator+(int64_t a, const Montgomery &b) {return Montgomery(a) + b;}
  friend auto operator-(int64_t a, const Montgomery &b) {return Montgomery(a) - b;}
  friend auto operator*(int64_t a, const Montgomery &b) {return Montgomery(a) * b;}
  friend auto operator/(int64_t a, const Montgomery &b) {return Montgomery(a) / b;}

  bool operator==(const Montgomery &that) const {
    return (val >= MOD ? val - MOD : val) == (that.val >= MOD ? that.val - MOD : that.val);
  }
  
  bool operator!=(const Montgomery &that) const {return !(*this == that);}
  
  friend std::ostream& operator<<(std::ostream& s, const Montgomery &a){
    return s << reduce(a.val);
  }

  friend std::istream& operator>>(std::istream& s, Montgomery &a){
    int64_t t; s >> t;
    a = Montgomery(t);
    return s;
  }

  explicit operator int32_t() const {return reduce(val);}
  explicit operator int64_t() const {return reduce(val);}
};






namespace solver{
  void init(){
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(12);
    std::cerr << std::fixed << std::setprecision(12);
    std::cin.exceptions(std::ios_base::failbit);
  }

  //using mint = ModInt<1000000007>;
  using mint = Montgomery<1000000007>;

  int64_t f(int64_t a, int64_t m, int64_t n){
    int64_t ret = 0;
    if(a >= m) ret += (n - 1) * n * (a / m) / 2, a %= m;

    auto y_max = (a * n) / m;
    auto x_max = y_max * m;
    if(y_max == 0) return ret;
    ret += (n - (x_max + a - 1) / a) * y_max;
    ret += f(m, a, y_max);

    return ret;
  }
  
  void solve(){
    int64_t N, M; std::cin >> N >> M;
    std::vector<int64_t> A(N), B(M); std::cin >> A >> B;

    mint ans = 0;

    for(auto a : A){
      for(auto b : B){
        ans += f(a, b, b + 1) * 2;
      }
    }

    std::cout << ans << "\n";
  }
}

int main(){
  solver::init();
  while(true){
    try{
      solver::solve();
    }catch(const std::istream::failure &e){
      break;
    }
  }
  return 0;
}
0