QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#497414#6126. Sequence and Sequenceucup-team1198AC ✓1787ms98660kbC++1414.0kb2024-07-29 04:40:352024-07-29 04:40:36

Judging History

你现在查看的是最新测评结果

  • [2024-07-29 04:40:36]
  • 评测
  • 测评结果:AC
  • 用时:1787ms
  • 内存:98660kb
  • [2024-07-29 04:40:35]
  • 提交

answer

#include <map>
#include <set>
#include <array>
#include <cmath>
#include <deque>
#include <bitset>
#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>

using namespace std;

int maxlen = 0;

struct BigInt {
  static const long long BASE = 100'000'000;
  static const int BASELEN = 8;

  vector<long long> digits;
  bool sign; // true: >= 0

  BigInt(long long x = 0) {
    if (x < 0) {
      sign = false;
      x *= -1;
    } else {
      sign = true;
    }
    while (x) {
      digits.emplace_back(x % BASE);
      x /= BASE;
    }
  }
  BigInt(string s) {
    sign = true;
    reverse(s.begin(), s.end());
    if (s.back() == '-') {
      sign = false;
      s.pop_back();
    }
    for (int i = 0; i < s.size(); i += BASELEN) {
      long long cur = 0;
      long long ten_pw = 1;
      for (int j = i; j < s.size() && j < i + BASELEN; ++j) {
        cur += ten_pw * (s[j] - '0');
        ten_pw *= 10;
      }
      digits.emplace_back(cur);
    }
  }

  explicit operator int() {
    int res = 0;
    for (int i = (int)digits.size() - 1; i >= 0; --i) {
        res = res * BASE + digits[i];
    }
    return res;
  }

  void fixup() {
      /// maxlen = max(maxlen, (int)digits.size());
    while (!digits.empty() && digits.back() == 0)
      digits.pop_back();
    if (digits.empty())
      sign = true;
  }
  BigInt(vector<long long> digits, bool sign): digits(digits), sign(sign) {
    fixup();
  }

  static bool compare_digits(vector<long long> left, vector<long long> right) {
    if (left.size() != right.size()) {
      return left.size() < right.size();
    }
    for (int i = int(left.size()) - 1; i >= 0; --i) {
      if (left[i] != right[i])
        return left[i] < right[i];
    }
    return false;
  }

  static vector<long long> add_digits(const vector<long long>& left, const vector<long long>& right) {
    vector<long long> ans(max(left.size(), right.size()) + 1);
    for (int i = 0; i < left.size(); ++i) {
      ans[i] += left[i];
    }
    for (int i = 0; i < right.size(); ++i) {
      ans[i] += right[i];
    }
    for (int i = 0; i + 1 < ans.size(); ++i) {
      if (ans[i] >= BASE) {
        ++ans[i + 1];
        ans[i] -= BASE;
      }
    }
    return ans;
  }

  // left >= right
  static vector<long long> sub_digits(const vector<long long>& left, const vector<long long>& right) {
    vector<long long> ans = left;
    for (int i = 0; i < right.size(); ++i)
      ans[i] -= right[i];
    for (int i = 0; i + 1 < left.size(); ++i) {
      if (ans[i] < 0) {
        ans[i] += BASE;
        --ans[i + 1];
      }
    }
    return ans;
  }

  void smart_add(const vector<long long>& other_digits, bool same_sign) {
    if (same_sign) {
      digits = add_digits(digits, other_digits);
    } else {
      if (compare_digits(digits, other_digits)) {
        sign ^= 1;
        digits = sub_digits(other_digits, digits);
      } else {
        digits = sub_digits(digits, other_digits);
      }
    }
    fixup();
  }

  BigInt& operator+=(const BigInt& other) {
    smart_add(other.digits, sign == other.sign);
    return *this;
  }

  BigInt& operator-=(const BigInt& other) {
    smart_add(other.digits, sign != other.sign);
    return *this;
  }

  bool operator==(const BigInt& other) const {
    return digits == other.digits && sign == other.sign;
  }

  bool operator<(const BigInt& other) const {
    if (sign && other.sign) {
      return compare_digits(digits, other.digits);
    } else if (sign) {
      return false;
    } else if (other.sign) {
      return true;
    } else {
      return compare_digits(other.digits, digits);
    }
  }

  BigInt& operator/=(long long x) {
    for (int i = int(digits.size()) - 1; i >= 0; --i) {
      long long r = digits[i] % x;
      digits[i] /= x;
      if (i)
        digits[i - 1] += r * BASE;
    }
    fixup();
    return *this;
  }

  bool is_zero() const {
    return digits.empty();
  }
};

BigInt operator+(const BigInt& a, const BigInt& b) {
  BigInt copy = a;
  copy += b;
  return copy;
}

BigInt operator-(const BigInt& a, const BigInt& b) {
  BigInt copy = a;
  copy -= b;
  return copy;
}

BigInt operator*(const BigInt& a, const BigInt& b) {
    /// maxlen = max((size_t)maxlen, a.digits.size() * b.digits.size());
  vector<long long> ans(a.digits.size() + b.digits.size());
  for (int i = 0; i < a.digits.size(); ++i) {
    for (int j = 0; j < b.digits.size(); ++j)
      ans[i + j] += a.digits[i] * b.digits[j];
  }
  for (int i = 0; i + 1 < ans.size(); ++i) {
    if (ans[i] >= BigInt::BASE) {
        long long d = ans[i] / BigInt::BASE;
      ans[i + 1] += d;
      ans[i] -= d * BigInt::BASE;
    }
  }
  return BigInt(ans, a.sign ^ b.sign ^ 1);
}

int get_len(long long x) {
  int ans = 0;
  while (x) {
    x /= 10;
    ++ans;
  }
  return ans;
}

ostream& operator<<(ostream& os, const BigInt& a) {
  if (!a.sign)
    os << '-';
  if (a.is_zero())
    os << 0;
  for (int i = 0; i < a.digits.size(); ++i) {
    long long cur = a.digits[a.digits.size() - i - 1];
    if (i != 0) {
      for (int j = 0; j < BigInt::BASELEN - get_len(cur); ++j)
        os << 0;
    }
    os << cur;
  }
  return os;
}

BigInt operator/(BigInt a, int b) {
    a /= b;
    return a;
}

BigInt get_P(BigInt n) {
    BigInt l = 1, r = n;
    while (BigInt(1) < r - l) {
        BigInt m = (l + r) / 2;
        if (n < m * (m + 1) / 2) {
            r = m;
        } else {
            l = m;
        }
    }
    return l;
}

const int SMALL = 100;
BigInt C[SMALL][SMALL];

const int MAXQ = 2e5;
BigInt Q[MAXQ];

vector<BigInt> expand(vector<BigInt> vals, int N) {
    int k = vals.size();
    for (int n = k; n < N; ++n) {
        vals.push_back(BigInt(0));
        for (int d = 1; d <= k; ++d) {
            if (d % 2 == 1) {
                vals[n] += vals[n - d] * C[k][d];
            } else {
                vals[n] -= vals[n - d] * C[k][d];
            }
        }
    }
    return vals;
}

vector<BigInt> convert(vector<BigInt> vals) {
    int k = vals.size();
    vector<BigInt> ans;
    for (int i = 0; i < k; ++i) {
        ans.push_back(vals[i]);
        BigInt d = vals[i];
        for (int j = i; j < k; ++j) {
            vals[j] -= d * C[j][i];
        }
    }
    return ans;
}

vector<BigInt> mulx(const vector<BigInt>& a) {
    vector<BigInt> res = expand(a, a.size() + 1);
    for (int i = 0; i < (int)res.size(); ++i) {
        res[i] = res[i] * i;
    }
    return res;
}

vector<BigInt> integ(const vector<BigInt>& a) {
    vector<BigInt> b(a.size() + 1);
    b[0] = 0;
    for (int i = 0; i < (int)a.size(); ++i) {
        b[i + 1] = a[i] + b[i];
    }
    return b;
}

BigInt eval(const vector<BigInt>& a, BigInt n) {
    BigInt res = 0;
    BigInt c = 1;
    for (int i = 0; i < (int)a.size(); ++i) {
        res += a[i] * c;
        c = c * (n - i);
        c /= (i + 1);
    }
    return res;
}

vector<BigInt> compose(const vector<BigInt>& a, const vector<BigInt>& b, const vector<BigInt>& ca) {
    int sz = (a.size() - 1) * (b.size() - 1) + 1;
    vector<BigInt> res(sz);
    vector<BigInt> valb = expand(b, sz);
    /// vector<BigInt> ca = convert(a);
    for (int i = 0; i < sz; ++i) {
        res[i] = eval(ca, valb[i]);
    }
    return res;
}

vector<BigInt> operator+(vector<BigInt> a, vector<BigInt> b) {
    int sz = max(a.size(), b.size());
    a = expand(a, sz);
    b = expand(b, sz);
    for (int i = 0; i < (int)a.size(); ++i) {
        a[i] += b[i];
    }
    return a;
}

vector<BigInt> operator-(vector<BigInt> a, vector<BigInt> b) {
    int sz = max(a.size(), b.size());
    a = expand(a, sz);
    b = expand(b, sz);
    for (int i = 0; i < (int)a.size(); ++i) {
        a[i] -= b[i];
    }
    return a;
}

vector<BigInt> operator*(vector<BigInt> a, vector<BigInt> b) {
    int sz = a.size() + b.size() - 1;
    a = expand(a, sz);
    b = expand(b, sz);
    for (int i = 0; i < sz; ++i) {
        a[i] = a[i] * b[i];
    }
    return a;
}

const int MAXTIER = 3;

vector<BigInt> tier[MAXTIER];
vector<BigInt> cStier[MAXTIER];
vector<BigInt> cStierx[MAXTIER];
BigInt pref[MAXTIER][MAXQ];

void ensure(vector<BigInt>& a, int n) {
    while (n >= (int)a.size()) {
        a.push_back(0);
    }
}

BigInt get_Q_bfs(BigInt n) {
    BigInt ans = 0;
    BigInt k = 1;
    BigInt cur_n = n;
    vector<BigInt> coeff;
    while (!coeff.empty() || !(k == 0)) {
        /// maxlen = max(maxlen, (int)coeff.size());
        /// cerr << k << " " << coeff.size() << " " << cur_n << endl;
        BigInt k1 = 0;
        vector<BigInt> coeff1 = {};
        BigInt n1 = get_P(cur_n);
        if (!(k == BigInt(0))) {
            BigInt n = cur_n;
            if (n < BigInt(MAXQ)) {
                ans += Q[int(n)] * k;
            } else {
                k1 -= ((n1 + 2) * (n1 + 1) / 2 - 1 - n) * k;
                ensure(coeff1, 0);
                coeff1[0] += k;
                /// vector<BigInt> cur = {k, k + k};
                /// vals1 = vals1 + cur;
            }
        }
        if (!coeff.empty()) {
            BigInt N = cur_n;
            if (N < MAXQ) {
                /**vals = expand(vals, int(N) + 1);
                for (int i = 1; i <= int(N); ++i) {
                    ans += vals[i] * Q[i];
                }*/
                for (int i = 0; i < (int)coeff.size(); ++i) {
                    ans += coeff[i] * pref[i][int(N)];
                }
            } else {
                for (int i = 0; i < (int)coeff.size(); ++i) {
                    BigInt cSfN = eval(cStier[i], N + 1);
                    BigInt k = eval(cStierx[i], (n1 + 1) * (n1 + 2) / 2) - eval(cStierx[i], N + 1);
                    k -= (n1 * (n1 + 1) / 2 + n1) * (eval(cStier[i], (n1 + 1) * (n1 + 2) / 2) - cSfN);
                    k1 -= k * coeff[i];
                    ensure(coeff1, i + 1);
                    coeff1[0] += cSfN * coeff[i];
                    coeff1[i + 1] += coeff[i];
                }
                /**vector<BigInt> Sf = integ(vals);
                vector<BigInt> Sfx = integ(mulx(vals));
                vector<BigInt> cSf = convert(Sf), cSfx = convert(Sfx);

                BigInt cSfN = eval(cSf, N + 1);
                BigInt k = eval(cSfx, (n1 + 1) * (n1 + 2) / 2) - eval(cSfx, N + 1);
                k -= (n1 * (n1 + 1) / 2 + n1) * (eval(cSf, (n1 + 1) * (n1 + 2) / 2) - cSfN);
                vector<BigInt> compSf = compose(Sf, {BigInt(0), BigInt(1), BigInt(3)}, cSf);
                vector<BigInt> compSf1 = expand(compSf, compSf.size() + 1);
                for (int i = 0; i < (int)compSf.size(); ++i) {
                    compSf1[i] = compSf1[i + 1];
                }
                compSf1.pop_back();
                vector<BigInt> compSfx = compose(Sfx, {BigInt(0), BigInt(1), BigInt(3)}, cSfx);
                vector<BigInt> compSfx1 = expand(compSfx, compSfx.size() + 1);
                for (int i = 0; i < (int)compSfx.size(); ++i) {
                    compSfx1[i] = compSfx1[i + 1];
                }
                compSfx1.pop_back();

                vector<BigInt> f = {cSfN};
                f = f - compSf1;
                f = f + mulx(f);
                f = f + compSfx1 - compSfx;
                vector<BigInt> sb = compSf1 - compSf;
                vector<BigInt> mlt = {BigInt(-1), BigInt(0), BigInt(2)};
                f = f - sb * mlt;
                vals1 = vals1 + f;
                k1 -= k;*/
            }
        }
        cur_n = n1;
        coeff = move(coeff1);
        k = k1;
    }
    return ans;
}

/// BigInt crutch = 0;

void solve() {
    string sn = "10000000000000000000000000000000000000000";
    cin >> sn;
    BigInt n(sn);

    /// crutch += get_Q_bfs(n);
    cout << get_Q_bfs(n) << "\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  auto start = clock();

  for (int n = 0; n < SMALL; ++n) {
    C[n][0] = 1;
    for (int k = 1; k <= n; ++k) {
        C[n][k] = C[n - 1][k - 1] + C[n - 1][k];
    }
  }

  /// cerr << (clock() - start) * 1.0 / CLOCKS_PER_SEC << endl;

  Q[1] = 1;
  int j = 1;
  for (int i = 2; i < MAXQ; ++i) {
    if ((j + 1) * (j + 2) / 2 == i) ++j;
    Q[i] = Q[i - 1] + Q[j];
  }

  tier[0] = {BigInt(1), BigInt(2)};
  for (int i = 1; i < MAXTIER; ++i) {
    vector<BigInt> vals = tier[i - 1];
    vector<BigInt> Sf = integ(vals);
    vector<BigInt> Sfx = integ(mulx(vals));
    vector<BigInt> cSf = convert(Sf), cSfx = convert(Sfx);

    vector<BigInt> compSf = compose(Sf, {BigInt(0), BigInt(1), BigInt(3)}, cSf);
    vector<BigInt> compSf1 = expand(compSf, compSf.size() + 1);
    for (int i = 0; i < (int)compSf.size(); ++i) {
        compSf1[i] = compSf1[i + 1];
    }
    compSf1.pop_back();
    vector<BigInt> compSfx = compose(Sfx, {BigInt(0), BigInt(1), BigInt(3)}, cSfx);
    vector<BigInt> compSfx1 = expand(compSfx, compSfx.size() + 1);
    for (int i = 0; i < (int)compSfx.size(); ++i) {
        compSfx1[i] = compSfx1[i + 1];
    }
    compSfx1.pop_back();

    vector<BigInt> f = {};
    f = f - compSf1;
    f = f + mulx(f);
    f = f + compSfx1 - compSfx;
    vector<BigInt> sb = compSf1 - compSf;
    vector<BigInt> mlt = {BigInt(-1), BigInt(0), BigInt(2)};
    f = f - sb * mlt;
    tier[i] = f;
  }
  /// cerr << "tiers found" << endl;
  for (int i = 0; i < MAXTIER; ++i) {
    cStier[i] = convert(integ(tier[i]));
    cStierx[i] = convert(integ(mulx(tier[i])));
    pref[i][0] = 0;
    auto res = expand(tier[i], MAXQ);
    /// cerr << i << endl;
    for (int n = 1; n < MAXQ; ++n) {
        pref[i][n] = pref[i][n - 1] + Q[n] * res[n];
    }
  }

  /// cerr << (clock() - start) * 1.0 / CLOCKS_PER_SEC << endl;

  int tst = 1;
  cin >> tst;
  while (tst--) {
    solve();
    /// cout.flush();
  }
  /// cerr << maxlen << endl;
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 780ms
memory: 98420kb

input:

4
10
100
1000
987654321123456789

output:

30
2522
244274
235139898689017607381017686096176798

result:

ok 4 lines

Test #2:

score: 0
Accepted
time: 1149ms
memory: 98300kb

input:

10000
613939207402503646
408978283345333197
976677512231308716
629053280913850466
148712339
236220313279945487
590396556995977994
9226
215693877607285701
649702683896705
343173887453826567
847003949499596615
867133040287550291
159928123569892354
864534948175618654
209739383170746721
4295456752378791...

output:

91030728117067063595428375419346402
40469246710473908695676971059074376
229951682342450470520349294486964970
95558039501640054006660579352994194
5418340556433412
13536357243714243974772906966693552
84197207203086091733385317631619504
20934656
11291075621624104092841708040651034
104019777231815308683...

result:

ok 10000 lines

Test #3:

score: 0
Accepted
time: 880ms
memory: 98504kb

input:

1000
6403632579734162001008235137760132245297
1307698664787972023762442022139627469666
668870338048562416595095770565441759482
5092270
8806864498496723812760785099973409980711
2178464116010775202899984038946879469187
204381824371
8638495456004772442511643693521120926431
45954412333082528168092594892...

output:

9822905445826021159291522774438593145331066315784567505849706373529921001845336
409552844852728078841401625660602682494169687360338453221088647649526339235330
107160056181509722327918304399871120167096186888511567354513496578559803370274
6354453295964
185817323129718525790559571287806776421589155460...

result:

ok 1000 lines

Test #4:

score: 0
Accepted
time: 986ms
memory: 98556kb

input:

2000
2587627816607030340103003175959756184662
7728753705064569253253827797978613582938
6507847628603052973674714721
6989857636824717968431061258300652290539
4734281027640913533293237760425416005062
9411123735455625690768098631226366597446
8309753930995253536640660321476246470149
63565157427098067709...

output:

1603610451790269237852635641930301658193367441164307312552842461667027137613454
14309943493171496191506053530749878345271155973702143153225815632926701434642842
10414697803791950572309383355053080338229465674803757518
11704102206894264239190418551798088411458157423624785417336589284698838535371266
5...

result:

ok 2000 lines

Test #5:

score: 0
Accepted
time: 1283ms
memory: 98660kb

input:

5000
6701025283447923273597553918313900029215
1618190467906965189844764312914748628527
2135261797018456059451326428589353332126
8027429917075086154217136768450383650445
8263301530632040969183919589286944799002
376886964626613356031779878
1191561726595055348898524031899625958102
453561433135467095374...

output:

10756647971303093856509780939435968749671842310025383400207261624750784751725876
627115945498078452730193858129037650151913122482133071938783012929533045529940
1091921493223233296724616654299408127388059493196845968361252389122720100379070
154375707400033063668088306493199269136326791073281723548116...

result:

ok 5000 lines

Test #6:

score: 0
Accepted
time: 1787ms
memory: 98496kb

input:

10000
260865660295317278841
5232352637620496342310336202478387251106
7108789244285764135987032973912918380
12766535319519586095540974948550152061
5138306300154916887884637635208203681949
7603163140266839847784708214115317398585
149590294591155205497765668766786424787
63283557694500045989299147454323...

output:

16323111740957704392106241109891718054228
6557703685144914472554701877112177422100848067214049191882271294010013621817762
12143115079716078114619105501427985631361994195400195527663921137836417758
39139456824156526604158618001888125076786817219954316014947704612553450312
6324051018379978443719363340...

result:

ok 10000 lines