結果

問題 No.2595 Parsing Challenge
ユーザー KudeKude
提出日時 2023-12-23 08:05:49
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 10,246 bytes
コンパイル時間 5,777 ms
コンパイル使用メモリ 331,748 KB
実行使用メモリ 270,020 KB
最終ジャッジ日時 2024-09-27 12:14:55
合計ジャッジ時間 32,223 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,816 KB
testcase_02 AC 2 ms
6,812 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 2 ms
6,940 KB
testcase_05 AC 2 ms
6,940 KB
testcase_06 AC 2 ms
6,940 KB
testcase_07 AC 2 ms
6,944 KB
testcase_08 AC 2 ms
6,944 KB
testcase_09 AC 2 ms
6,944 KB
testcase_10 AC 2 ms
6,944 KB
testcase_11 AC 2 ms
6,940 KB
testcase_12 AC 2 ms
6,940 KB
testcase_13 AC 2 ms
6,940 KB
testcase_14 AC 2 ms
6,940 KB
testcase_15 AC 2 ms
6,944 KB
testcase_16 AC 2 ms
6,940 KB
testcase_17 AC 2 ms
6,944 KB
testcase_18 AC 2 ms
6,940 KB
testcase_19 AC 2 ms
6,944 KB
testcase_20 AC 3 ms
6,944 KB
testcase_21 AC 4 ms
6,944 KB
testcase_22 AC 3 ms
6,940 KB
testcase_23 AC 3 ms
6,940 KB
testcase_24 AC 3 ms
6,944 KB
testcase_25 AC 13 ms
6,940 KB
testcase_26 AC 14 ms
6,944 KB
testcase_27 AC 13 ms
6,944 KB
testcase_28 AC 13 ms
6,940 KB
testcase_29 AC 14 ms
6,944 KB
testcase_30 AC 110 ms
6,944 KB
testcase_31 AC 107 ms
6,940 KB
testcase_32 AC 109 ms
6,940 KB
testcase_33 AC 113 ms
6,944 KB
testcase_34 AC 110 ms
6,940 KB
testcase_35 AC 627 ms
20,836 KB
testcase_36 AC 631 ms
22,972 KB
testcase_37 AC 634 ms
23,408 KB
testcase_38 AC 640 ms
21,988 KB
testcase_39 AC 628 ms
22,440 KB
testcase_40 AC 17 ms
8,376 KB
testcase_41 AC 18 ms
8,256 KB
testcase_42 AC 17 ms
8,256 KB
testcase_43 AC 272 ms
270,020 KB
testcase_44 AC 84 ms
6,944 KB
testcase_45 AC 82 ms
6,940 KB
testcase_46 AC 83 ms
6,944 KB
testcase_47 AC 83 ms
6,944 KB
testcase_48 AC 84 ms
6,940 KB
testcase_49 AC 459 ms
9,128 KB
testcase_50 AC 460 ms
9,304 KB
testcase_51 AC 461 ms
9,160 KB
testcase_52 AC 2,269 ms
9,948 KB
testcase_53 AC 2,275 ms
10,236 KB
testcase_54 AC 2,258 ms
9,948 KB
testcase_55 AC 2,267 ms
9,952 KB
testcase_56 AC 2,274 ms
10,080 KB
testcase_57 TLE -
testcase_58 -- -
testcase_59 -- -
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp:359:8: warning: '{anonymous}::bigint {anonymous}::operator-(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  359 | bigint operator -(const bigint &A, const bigint &B){
      |        ^~~~~~~~
main.cpp:338:8: warning: '{anonymous}::bigint {anonymous}::operator+(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  338 | bigint operator +(const bigint &A, const bigint &B){
      |        ^~~~~~~~
main.cpp:315:8: warning: '{anonymous}::bigint {anonymous}::operator-(const bigint&)' defined but not used [-Wunused-function]
  315 | bigint operator -(const bigint &A){
      |        ^~~~~~~~
main.cpp:312:8: warning: '{anonymous}::bigint {anonymous}::operator+(const bigint&)' defined but not used [-Wunused-function]
  312 | bigint operator +(const bigint &A){
      |        ^~~~~~~~
main.cpp:309:6: warning: 'bool {anonymous}::operator>=(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  309 | bool operator >=(const bigint &A, const bigint &B){
      |      ^~~~~~~~
main.cpp:306:6: warning: 'bool {anonymous}::operator<=(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  306 | bool operator <=(const bigint &A, const bigint &B){
      |      ^~~~~~~~
main.cpp:303:6: warning: 'bool {anonymous}::operator>(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  303 | bool operator >(const bigint &A, const bigint &B){
      |      ^~~~~~~~
main.cpp:300:6: warning: 'bool {anonymous}::operator<(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  300 | bool operator <(const bigint &A, const bigint &B){
      |      ^~~~~~~~
main.cpp:297:6: warning: 'bool {anonymous}::operator!=(const bigint&, const bigint&)' defined but not used [-Wunused-function]
  297 | bool operator !=(const bigint &A, const bigint &B){
      |      ^~~~~~~~
main.cpp:294:6: warning: 'bool {anonymous}::operator==(const bigint&, const bigint&)' defined but not used [-Wunused-fu

ソースコード

diff #

#include<bits/stdc++.h>
namespace {
#pragma GCC diagnostic ignored "-Wunused-function"
#include<atcoder/all>
#pragma GCC diagnostic warning "-Wunused-function"
using namespace std;
using namespace atcoder;
#define rep(i,n) for(int i = 0; i < (int)(n); i++)
#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; }
template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; }
using ll = long long;
using P = pair<int,int>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;


constexpr int DIGIT = 6;
constexpr int BASE = 1000000;
struct positive_bigint{
  std::vector<int> d;
  positive_bigint(){
  }
  positive_bigint(long long X){
    while (X > 0){
      d.push_back(X % BASE);
      X /= BASE;
    }
  }
  positive_bigint(std::string S){
    if (S == "0"){
      S = "";
    }
    int L = S.size();
    d.resize((L + DIGIT - 1) / DIGIT, 0);
    for (int i = L - 1; i >= 0; i -= 6){
      for (int j = std::max(i - 5, 0); j <= i; j++){
        d[i / DIGIT] *= 10;
        d[i / DIGIT] += S[j] - '0';
      }
    }
    std::reverse(d.begin(), d.end());
  }
  bool empty() const {
    return d.empty();
  }
  int size() const {
    return d.size();
  }
  int& operator [](int i){
    return d[i];
  }
  int operator [](int i) const {
    return d[i];
  }
};
std::string to_string(const positive_bigint &A){
  int N = A.size();
  std::string ans;
  for (int i = N - 1; i >= 0; i--){
    std::string tmp = std::to_string(A[i]);
    if (i < N - 1){
      ans += std::string(DIGIT - tmp.size(), '0');
    }
    ans += tmp;
  }
  if (ans.empty()){
    ans = "0";
  }
  return ans;
}
std::istream& operator >>(std::istream &is, positive_bigint &A){
  std::string S;
  is >> S;
  A = positive_bigint(S);
  return is;
}
std::ostream& operator <<(std::ostream &os, positive_bigint &A){
  os << to_string(A);
  return os;
}
int cmp(const positive_bigint &A, const positive_bigint &B){
  int N = A.size();
  int M = B.size();
  if (N < M){
    return -1;
  } else if (N > M){
    return 1;
  } else {
    for (int i = N - 1; i >= 0; i--){
      if (A[i] < B[i]){
        return -1;
      }
      if (A[i] > B[i]){
        return 1;
      }
    }
    return 0;
  }
}
bool operator ==(const positive_bigint &A, const positive_bigint &B){
  return cmp(A, B) == 0;
}
bool operator !=(const positive_bigint &A, const positive_bigint &B){
  return cmp(A, B) != 0;
}
bool operator <(const positive_bigint &A, const positive_bigint &B){
  return cmp(A, B) < 0;
}
bool operator >(const positive_bigint &A, const positive_bigint &B){
  return cmp(A, B) > 0;
}
bool operator <=(const positive_bigint &A, const positive_bigint &B){
  return cmp(A, B) <= 0;
}
bool operator >=(const positive_bigint &A, const positive_bigint &B){
  return cmp(A, B) >= 0;
}
positive_bigint& operator +=(positive_bigint &A, const positive_bigint &B){
  int N = A.size();
  int M = B.size();
  while (N < M){
    A.d.push_back(0);
    N++;
  }
  // ?
  bool carry = false;
  for (int i = 0; i < M; i++) {
    A[i] += B[i] + carry;
    carry = A[i] >= BASE;
    if (carry) A[i] -= BASE;
  }
  if (carry) {
    int i = M;
    for (; i < N; i++) {
      if (A[i] < BASE - 1) {
        A[i]++;
        break;
      }
      A[i] = 0;
    }
    if (i == N) A.d.push_back(1);
  }
  // if (N > 0){
  //   if (A[N - 1] >= BASE){
  //     A.d.push_back(1);
  //     A[N - 1] -= BASE;
  //   }
  // }
  return A;
}
positive_bigint operator +(const positive_bigint &A, const positive_bigint &B){
  positive_bigint A2 = A;
  A2 += B;
  return A2;
}
positive_bigint& operator -=(positive_bigint &A, const positive_bigint &B){
  int N = A.size();
  int M = B.size();
  for (int i = 0; i < M; i++){
    A[i] -= B[i];
  }
  for (int i = 0; i < N - 1; i++){
    if (A[i] < 0){
      A[i] += BASE;
      A[i + 1]--;
    }
  }
  while (!A.empty()){
    if (A.d.back() == 0){
      A.d.pop_back();
    } else {
      break;
    }
  }
  return A;
}
positive_bigint operator -(const positive_bigint &A, const positive_bigint &B){
  positive_bigint A2 = A;
  A2 -= B;
  return A2;
}
positive_bigint operator *(const positive_bigint &A, const positive_bigint &B){
  if (A.empty() || B.empty()){
    return 0;
  }
  int N = A.size();
  int M = B.size();
  std::vector<long long> a(N);
  for (int i=  0; i < N; i++){
    a[i] = A[i];
  }
  std::vector<long long> b(M);
  for (int i = 0; i < M; i++){
    b[i] = B[i];
  }
  std::vector<long long> C = atcoder::convolution_ll(a, b);
  for (int i = 0; i < N + M - 2; i++){
    C[i + 1] += C[i] / BASE;
    C[i] %= BASE;
  }
  while (C.back() >= BASE) {
    long long x = C.back();
    C.back() = x % BASE;
    C.push_back(x / BASE);
  }
  // if (C[N + M - 2] >= BASE){
  //   C.resize(N + M);
  //   C[N + M - 1] += C[N + M - 2] / BASE;
  //   C[N + M - 2] %= BASE;
  // }
  positive_bigint ans;
  ans.d.resize(C.size());
  for (int i = 0; i < ssize(C); i++){
    ans[i] = C[i];
  }
  return ans;
}
positive_bigint operator *=(positive_bigint &A, const positive_bigint &B){
  A = A * B;
  return A;
}
struct bigint{
  bool neg = false;
  positive_bigint a;
  bigint(){
  }
  bigint(long long X): neg(X < 0), a(abs(X)){
  }
  bigint(const positive_bigint &X, bool neg = false): neg(neg), a(X){
  }
  bigint(const std::string &s){
    if (!s.empty()){
      if (s[0] == '-'){
        neg = true;
        a = positive_bigint(s.substr(1, s.size() - 1));
      } else {
        a = positive_bigint(s);
      }
    }
  }
  bool empty() const {
    return a.empty();
  }
  int size() const {
    return a.size();
  }
  int& operator [](int i){
    return a[i];
  }
};
std::string to_string(const bigint &A){
  std::string ans;
  if (A.neg){
    ans += '-';
  }
  ans += to_string(A.a);
  return ans;
}
std::istream& operator >>(std::istream &is, bigint &A){
  std::string S;
  is >> S;
  if (S != "0"){
    A = bigint(S);
  }
  return is;
}
std::ostream& operator <<(std::ostream &os, bigint A){
  os << to_string(A);
  return os;
}
positive_bigint abs(const bigint &A){
  return A.a;
}
int cmp(const bigint &A, const bigint &B){
  if (!A.neg){
    if (!B.neg){
      return cmp(A.a, B.a);
    } else {
      return 1;
    }
  } else {
    if (!B.neg){
      return -1;
    } else {
      return cmp(B.a, A.a);
    }
  }
}
bool operator ==(const bigint &A, const bigint &B){
  return cmp(A, B) == 0;
}
bool operator !=(const bigint &A, const bigint &B){
  return cmp(A, B) != 0;
}
bool operator <(const bigint &A, const bigint &B){
  return cmp(A, B) < 0;
}
bool operator >(const bigint &A, const bigint &B){
  return cmp(A, B) > 0;
}
bool operator <=(const bigint &A, const bigint &B){
  return cmp(A, B) <= 0;
}
bool operator >=(const bigint &A, const bigint &B){
  return cmp(A, B) >= 0;
}
bigint operator +(const bigint &A){
  return A;
}
bigint operator -(const bigint &A){
  bigint A2 = A;
  if (!A2.empty()){
    A2.neg = !A2.neg;
  }
  return A2;
}
bigint& operator +=(bigint &A, const bigint &B){
  if (A.neg == B.neg){
    A.a += B.a;
  } else {
    int c = cmp(A.a, B.a);
    if (c > 0){
      A.a -= B.a;
    } else if (c < 0){
      A.a = B.a - A.a;
      A.neg = !A.neg;
    } else {
      A = 0;
    }
  }
  return A;
}
bigint operator +(const bigint &A, const bigint &B){
  bigint A2 = A;
  A2 += B;
  return A2;
}
bigint& operator -=(bigint &A, const bigint &B){
  if (A.neg != B.neg){
    A.a += B.a;
  } else {
    int c = cmp(A.a, B.a);
    if (c > 0){
      A.a -= B.a;
    } else if (c < 0){
      A.a = B.a - A.a;
      A.neg = !A.neg;
    } else {
      A = 0;
    }
  }
  return A;
}
bigint operator -(const bigint &A, const bigint &B){
  bigint A2 = A;
  A2 -= B;
  return A2;
}
bigint operator *=(bigint &A, const bigint &B){
  if (A.empty() || B.empty()){
    A = 0;
  } else {
    if (B.neg){
      A.neg = !A.neg;
    }
    A.a *= B.a;
  }
  return A;
}
bigint operator *(const bigint &A, const bigint &B){
  bigint A2 = A;
  A2 *= B;
  return A2;
}



string s;
int ptr = 0;
bigint rd_expr();
optional<bigint> rd_term();
optional<bigint> rd_factor();
optional<bigint> rd_number();

optional<bigint> rd_number() {
  int l = ptr;
  while (isdigit(s[ptr])) ptr++;
  if (l == ptr) return {};
  bigint res = s.substr(l, ptr - l);
  return res;
}
optional<bigint> rd_factor() {
  bool neg = false;
  while (s[ptr] == '+') ptr++;
  while (s[ptr] == '-') neg ^= 1, ptr++;
  optional<bigint> res;
  if (s[ptr] == '(') {
    ptr++;
    res = rd_expr();
    assert(s[ptr] == ')');
    ptr++;
  } else {
    res = rd_number();
  }
  if (neg) {
    assert(res.has_value());
    res.value().neg ^= 1;
  }
  return res;
}
optional<bigint> rd_term() {
  vector<bigint> facts;
  while (true) {
    optional<bigint> res = rd_factor();
    if (!res) break;
    facts.push_back(move(res.value()));
    if (s[ptr] != '*') break;
    ptr++;
  }
  if (facts.empty()) return {};
  static queue<bigint> q;
  while (facts.size()) {
    q.emplace(move(facts.back()));
    facts.pop_back();
  }
  while (q.size() >= 2) {
    auto a = move(q.front());
    q.pop();
    auto b = move(q.front());
    q.pop();
    q.emplace(a * b);
  }
  auto res = move(q.back());
  q.pop();
  return res;
}
bigint rd_expr() {
  vector<bigint> terms;
  while (true) {
    optional<bigint> res = rd_term();
    if (!res) break;
    terms.push_back(move(res.value()));
  }
  static vector<bigint> poss, negs;
  poss.clear(); negs.clear();
  for (auto& t : terms) {
    (t.neg ? negs : poss).push_back(move(t));
  }
  bigint tot_pos, tot_neg;
  rep(_, 2) {
    if (!poss.empty()) {
      ranges::sort(poss, less{}, [](const auto& x) { return x.a.size(); });
      tot_pos = move(poss.back());
      poss.pop_back();
      while (!poss.empty()) {
        tot_pos += poss.back();
        poss.pop_back();
      }
    }
    swap(poss, negs);
    swap(tot_pos, tot_neg);
  }
  if (tot_pos.a < tot_neg.a) swap(tot_pos, tot_neg);
  tot_pos += tot_neg;
  return tot_pos;
}

} int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n >> s;
  s += '$';
  auto ans = rd_expr();
  assert(ptr == n);
  cout << ans << '\n';
}
0