結果

問題 No.3396 ChRisTmas memory
コンテスト
ユーザー hos.lyric
提出日時 2025-12-03 00:32:30
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,697 ms / 4,000 ms
コード長 3,155 bytes
コンパイル時間 1,040 ms
コンパイル使用メモリ 111,200 KB
実行使用メモリ 7,852 KB
最終ジャッジ日時 2025-12-03 00:33:08
合計ジャッジ時間 18,589 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 40
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:117:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  117 |       scanf("%d", &O);
      |       ~~~~~^~~~~~~~~~
main.cpp:120:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  120 |         scanf("%lld%lld", &m, &b);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~
main.cpp:124:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  124 |         scanf("%d", &K);
      |         ~~~~~^~~~~~~~~~
main.cpp:128:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  128 |         scanf("%lld", &m);
      |         ~~~~~^~~~~~~~~~~~

ソースコード

diff #
raw source code

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <chrono>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")


// a x + b y = (+/-) gcd(a, b)
//   (a, 0): g = a, x = 1, y = 0
//   (0, b), (b, b), (-b, b) (b != 0): g = b, x = 0, y = 1
//   otherwise: 2 |x| <= |b|, 2 |y| <= |a|
// S: signed integer
template <class S> S gojo(S a, S b, S &x, S &y) {
  if (b != 0) {
    const S g = gojo(b, a % b, y, x);
    y -= (a / b) * x;
    return g;
  } else {
    x = 1;
    y = 0;
    return a;
  }
}


vector<Int> M, B;

// x0 + m0 x1 + m0 m1 x2 + ...
// no sol <=> ms.back() = 0
vector<Int> ms, xs;

void init() {
  M.clear();
  B.clear();
  ms.clear();
  xs.clear();
}
Int get(Int m) {
  if (ms.size() && !ms.back()) {
    return -1;
  }
  Int x = 0;
  for (int i = (int)ms.size(); --i >= 0; ) {
    ((x *= ms[i]) += xs[i]) %= m;
  }
  return x;
}
void push(Int m, Int b) {
  M.push_back(m);
  B.push_back(b);
  if (ms.size() && !ms.back()) {
    ms.push_back(0);
    xs.push_back(0);
    return;
  }
  // x + a y == b  (mod m)
  Int a = 1;
  for (int i = (int)ms.size(); --i >= 0; ) (a *= ms[i]) %= m;
  Int s, t;
  const Int g = gojo(a, m, s, t);
  const Int x = get(m);
  if ((b - x) % g != 0) {
    ms.push_back(0);
    xs.push_back(0);
    return;
  }
  m /= g;
  Int y = ((b - x) / g * s) % m;
  if (y < 0) y += m;
  ms.push_back(m);
  xs.push_back(y);
}
void pop() {
  M.pop_back();
  B.pop_back();
  ms.pop_back();
  xs.pop_back();
}

int main() {
  int Q;
  for (; ~scanf("%d", &Q); ) {
    init();
    for (; Q--; ) {
      int O;
      scanf("%d", &O);
      if (O == 1) {
        Int m, b;
        scanf("%lld%lld", &m, &b);
        push(m, b);
      } else if (O == 2) {
        int K;
        scanf("%d", &K);
        for (; K--; ) pop();
      } else if (O == 3) {
        Int m;
        scanf("%lld", &m);
        const Int ans = get(m);
        printf("%lld\n", ans);
      } else {
        assert(false);
      }
// cerr<<"M = "<<M<<", B = "<<B<<": ms = "<<ms<<", xs = "<<xs<<endl;
    }
  }
  return 0;
}
0