QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#686968#9515. 无限地狱hos_lyric100 ✓5288ms13332kbC++1412.5kb2024-10-29 16:32:322024-10-29 16:32:32

Judging History

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

  • [2024-10-29 16:32:32]
  • 评测
  • 测评结果:100
  • 用时:5288ms
  • 内存:13332kb
  • [2024-10-29 16:32:32]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#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")

////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
  static constexpr unsigned M = M_;
  unsigned x;
  constexpr ModInt() : x(0U) {}
  constexpr ModInt(unsigned x_) : x(x_ % M) {}
  constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
  constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
  constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
  ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
  ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
  ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
  ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
  ModInt pow(long long e) const {
    if (e < 0) return inv().pow(-e);
    ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
  }
  ModInt inv() const {
    unsigned a = M, b = x; int y = 0, z = 1;
    for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
    assert(a == 1U); return ModInt(y);
  }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
  ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
  ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
  ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
  ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
  template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
  template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
  template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
  template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
  explicit operator bool() const { return x; }
  bool operator==(const ModInt &a) const { return (x == a.x); }
  bool operator!=(const ModInt &a) const { return (x != a.x); }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////

constexpr unsigned MO = 998244353;
using Mint = ModInt<MO>;


inline long long divide(long long a, int b) {
  return a / b;
}
inline long long divide(long long a, long long b) {
  return a / b;
}

struct Quotients {
  long long N;
  int N2, N3, N4, N6;
  int len;
  Quotients(long long N_ = 0) : N(N_) {
    N2 = sqrt(static_cast<long double>(N));
    N3 = cbrt(static_cast<long double>(N));
    for (; static_cast<long long>(N3) * N3 * N3 < N; ++N3) {}
    for (; static_cast<long long>(N3) * N3 * N3 > N; --N3) {}
    N4 = sqrt(static_cast<long double>(N2));
    N6 = sqrt(static_cast<long double>(N3));
    len = 2 * N2 + ((static_cast<long long>(N2) * (N2 + 1) <= N) ? 1 : 0);
  }
  long long operator[](int i) const {
    return (i <= N2) ? i : divide(N, len - i);
  }
  int indexOf(long long x) const {
    return (x <= N2) ? x : (len - divide(N, x));
  }
  friend std::ostream &operator<<(std::ostream &os, const Quotients &quo) {
    os << "[";
    for (int i = 0; i < quo.len; ++i) {
      if (i > 0) os << ", ";
      os << quo[i];
    }
    os << "]";
    return os;
  }
};

template <class T> struct Dirichlet {
  Quotients quo;
  vector<T> ts;
  Dirichlet(long long N = 0) : quo(N), ts(quo.len + 1) {}
  T operator[](int i) const {
    return ts[i];
  }
  T &operator[](int i) {
    return ts[i];
  }
  T operator()(long long x) const {
    return ts[quo.indexOf(x)];
  }
  T &operator()(long long x) {
    return ts[quo.indexOf(x)];
  }
  T point(int i) const {
    return ts[i] - ts[i - 1];
  }
  friend std::ostream &operator<<(std::ostream &os, const Dirichlet &A) {
    os << "[";
    for (int i = 1; i < A.quo.len; ++i) {
      if (i > 1) os << ", ";
      os << A.quo[i] << ":" << A.ts[i];
    }
    os << "]";
    return os;
  }

  friend Dirichlet operator*(const Dirichlet &A, const Dirichlet &B) {
    assert(A.quo.N == B.quo.N);
    const Quotients quo = A.quo;
    Dirichlet C(quo.N);
    // i = j <= N^(1/2)
    for (int i = 1; i <= quo.N4; ++i) {
      C[i * i] += A.point(i) * B.point(i);
    }
    for (int i = quo.N4 + 1; i <= quo.N2; ++i) {
      C[quo.len - divide(quo.N, static_cast<long long>(i) * i)]
          += A.point(i) * B.point(i);
    }
    // i < j <= (N/i)^(1/2)
    for (int i = 1; i <= quo.N3; ++i) {
      const T ai = A.point(i), bi = B.point(i);
      if (ai || bi) {
        const long long N_i = divide(quo.N, i);
        const int midJ = max(i, quo.N2 / i);
        const int limJ = sqrt(static_cast<long double>(N_i));
        for (int j = i + 1; j <= midJ; ++j) {
          C[i * j] += ai * B.point(j) + A.point(j) * bi;
        }
        for (int j = midJ + 1; j <= limJ; ++j) {
          C[quo.len - divide(N_i, j)] += ai * B.point(j) + A.point(j) * bi;
        }
      }
    }
    for (int i = 2; i < quo.len; ++i) C[i] += C[i - 1];
    // i < j && k <= (N/i)^(1/2) < j
    for (int i = 1; i <= quo.N3; ++i) {
      const T ai = A.point(i), bi = B.point(i);
      if (ai || bi) {
        const long long N_i = divide(quo.N, i);
        const int midK = quo.N2 / i;
        const int limK = sqrt(static_cast<long double>(N_i));
        for (int k = 1; k <= midK; ++k) {
          C[quo.len - k] +=
              ai * (B[quo.len - i * k] - B[limK]) + (A[quo.len - i * k] - A[limK]) * bi;
        }
        for (int k = midK + 1; k <= limK; ++k) {
          const int limJ = divide(N_i, k);
          C[quo.len - k] += ai * (B[limJ] - B[limK]) + (A[limJ] - A[limK]) * bi;
        }
      }
    }
    for (int i = quo.N3 + 1; i <= quo.N2; ++i) {
      const T ai = A.point(i), bi = B.point(i);
      if (ai || bi) {
        const long long N_i = divide(quo.N, i);
        const int midK = quo.N2 / i;
        const int limK = divide(N_i, i);
        for (int k = 1; k <= midK; ++k) {
          C[quo.len - k] += 
              ai * (B[quo.len - i * k] - B[i]) + (A[quo.len - i * k] - A[i]) * bi;
        }
        for (int k = midK + 1; k <= limK; ++k) {
          const int limJ = divide(N_i, k);
          C[quo.len - k] += ai * (B[limJ] - B[i]) + (A[limJ] - A[i]) * bi;
        }
      }
    }
    return C;
  }

  // TODO: operator/
  // TODO: * powerful
};


// a^e,  0 <= e < 2^32
struct Power {
  static constexpr int E = 18;
  vector<Mint> baby, giant;
  Power() {}
  Power(Mint a) : baby((1 << E) + 1), giant(1 << E) {
    baby[0] = 1;
    for (int i = 1; i <= 1 << E; ++i) baby[i] = baby[i - 1] * a;
    giant[0] = 1;
    for (int i = 1; i < 1 << E; ++i) giant[i] = giant[i - 1] * baby[1 << E];
  }
  Mint operator()(long long e) const {
    return giant[e >> E] * baby[e & ((1 << E) - 1)];
  }
} two(2);


Mint div2(Mint a) {
  (a.x += (a.x & 1) * MO) >>= 1;
  return a;
}

using Di = Dirichlet<Mint>;

// \sum[1<=i<=n] 2^(i/2)
Mint Half(Int n) {
  return (n&1 ? 4 : 3) * two(n/2) - 3;
}

int main() {
  Int N;
  for (; ~scanf("%lld", &N); ) {
    const Quotients quo(N);
    
    Di Moe(N);
    {
      vector<int> lpf(quo.N2 + 1, 0), moe(quo.N2 + 1, 0);
      for (int p = 2; p <= quo.N2; ++p) lpf[p] = p;
      moe[1] = 1;
      for (int p = 2; p <= quo.N2; ++p) if (lpf[p] == p) {
        for (int n = p; n <= quo.N2; n += p) {
          chmin(lpf[n], p);
          moe[n] = (n / p % p) ? -moe[n / p] : 0;
        }
      }
      
      for (int i = 1; i <= quo.N2; ++i) Moe[i] = moe[i];
      for (int i = 1; i < quo.len; ++i) Moe[i] += Moe[i - 1];
      Di Zeta(N);
      for (int i = 1; i < quo.len; ++i) Zeta[i] = quo[i];
      Di A = Zeta * Moe;
      for (int j = quo.N2 + 1; j < quo.len; ++j) {
        // A(N/k)
        A[j] = 1 - A[j];
        const int k = quo.len - j;
        for (int i = 2; quo.len - i * k > quo.N2; ++i) A[j] -= 1 * A[quo.len - i * k];
      }
      for (int i = quo.N2 + 1; i < quo.len; ++i) Moe[i] += A[i];
    }
// cerr<<"Moe = "<<Moe<<endl;
cerr<<COLOR("96")<<"DONE Moe "<<clock()<<COLOR()<<endl;
    
    /*
      [1, n-1]: palindrome
      A,B appears in this order
      gcd(B) = 1
      
      pal[n] = (\sum[d|n] mu[d] (2^(floor(n/d/2)) - 1)) - 2^(n/2 - 1)  (n >= 2)
      pal[1] = 0
    */
    Di Pal(N);
    {
      for (int i = 1; i < quo.len; ++i) {
        const Int n = quo[i];
        Pal[i] = Half(n);
      }
      Pal = Pal * Moe;
      for (int i = 1; i < quo.len; ++i) {
        const Int n = quo[i];
        Pal[i] -= (Half(n) + 1) / 2;
      }
    }
// cerr<<"Pal = "<<Pal<<endl;
cerr<<COLOR("96")<<"DONE Pal "<<clock()<<COLOR()<<endl;
    
    /*
      A,B appear in this order
      g2: gcd(B) = 1
        g2(n) = (\sum[1<=d<=n] mu(d) (2^(n/d) - 1)) - 2^(n-1)
              = (\sum[1<=i<=n] \sum[d|i] mu(d) 2^(i/d-1)) - 2^(n-1)
    */
    Di f2(N), g2(N);
    for (int i = 1; i < quo.len; ++i) f2[i] = two(quo[i]-1) - 1;
    for (int i = 1; i < quo.len; ++i) g2[i] = two(quo[i]) - 1;
    g2 = g2 * Moe;
    for (int i = 1; i < quo.len; ++i) g2[i] -= two(quo[i]-1);
cerr<<COLOR("96")<<"DONE g2 "<<clock()<<COLOR()<<endl;
    
    /*
      A,B,C appears in this order
      g := gcd(C)
      - g >= 2
      - non-multiples of g is determined by mod g
      - [1, g - 1] is palindrome
      - multiples of g: recursively (but gcd = 1)
      g3: gcd(B) = 1
    */
    Di f3(N), g3(N), iroiro(N);
    for (int i = 1; i < quo.len; ++i) {
      const Quotients q(quo[i]);
      // g >= 2
      Mint h = div2(Half(1)) - 1;
      for (int j = 2; j < q.len; ++j) {
        const Int gL = q[j - 1];
        const Int gR = q[j];
        const int ii = quo.indexOf(q[q.len - j]);
        // BC, BCA
        f3[i] += (gR - gL) * (g2[ii] + g3[ii]);
        // C, AC, BC, CA, CB, ACB, BCA, CAB, CBA
        // f3[i] += ((Half(gR) / 2 - gR) - (Half(gL) / 2 - gL)) * iroiro[ii];
        const Mint hh = div2(Half(gR)) - gR;
        f3[i] += (hh - h) * iroiro[ii];
        h = hh;
        g3[i] += (Pal(gR) - Pal(gL)) * iroiro[ii];
      }
      iroiro[i] = 1 + 2*g2[i] + 2*f2[i] + 2*g3[i] + 2*f3[i];
if(i==quo.N2)cerr<<COLOR("96")<<"DONE f3[sqrt(N)] "<<clock()<<COLOR()<<endl;
    }
/*
cerr<<"quo = "<<quo<<endl;
cerr<<"f2 = "<<f2<<endl;
cerr<<"f3 = "<<f3<<endl;
cerr<<"g2 = "<<g2<<endl;
cerr<<"g3 = "<<g3<<endl;
cerr<<"iroiro = "<<iroiro<<endl;
*/
    
    Mint ans = 0;
    ans += 1;
    ans += (two(N-1) - 1);
    ans += f3[quo.len - 1];
    printf("%u\n", ans.x);
  }
  return 0;
}
/*
f1 = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
f2 = [0, 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287]
f3 = [0, 0, 0, 0, 1, 2, 6, 9, 20, 28, 53, 68, 126, 157, 260, 338, 555, 682, 1112, 1367, 2218]
g2 = [0, 0, 0, 1, 3, 10, 21, 52, 108, 232, 471, 982, 1968, 4015, 8046, 16219, 32475, 65242, 130494, 261565, 523191]
g3 = [0, 0, 0, 0, 0, 1, 2, 5, 9, 15, 28, 43, 67, 98, 159, 224, 344, 471, 723, 978, 1492]
*/

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 4
Accepted

Test #1:

score: 4
Accepted
time: 3ms
memory: 5092kb

input:

6

output:

38

result:

ok 1 number(s): "38"

Test #2:

score: 4
Accepted
time: 3ms
memory: 5088kb

input:

7

output:

73

result:

ok 1 number(s): "73"

Test #3:

score: 4
Accepted
time: 3ms
memory: 5160kb

input:

8

output:

148

result:

ok 1 number(s): "148"

Test #4:

score: 4
Accepted
time: 0ms
memory: 5084kb

input:

9

output:

284

result:

ok 1 number(s): "284"

Test #5:

score: 4
Accepted
time: 3ms
memory: 5144kb

input:

10

output:

565

result:

ok 1 number(s): "565"

Subtask #2:

score: 13
Accepted

Dependency #1:

100%
Accepted

Test #6:

score: 13
Accepted
time: 3ms
memory: 5088kb

input:

30

output:

536938322

result:

ok 1 number(s): "536938322"

Test #7:

score: 13
Accepted
time: 3ms
memory: 5052kb

input:

35

output:

210046687

result:

ok 1 number(s): "210046687"

Test #8:

score: 13
Accepted
time: 3ms
memory: 5048kb

input:

38

output:

680532913

result:

ok 1 number(s): "680532913"

Test #9:

score: 13
Accepted
time: 3ms
memory: 5148kb

input:

39

output:

362030079

result:

ok 1 number(s): "362030079"

Test #10:

score: 13
Accepted
time: 3ms
memory: 5168kb

input:

40

output:

723529503

result:

ok 1 number(s): "723529503"

Subtask #3:

score: 17
Accepted

Dependency #2:

100%
Accepted

Test #11:

score: 17
Accepted
time: 3ms
memory: 5056kb

input:

2000

output:

686289840

result:

ok 1 number(s): "686289840"

Test #12:

score: 17
Accepted
time: 0ms
memory: 5144kb

input:

2500

output:

672176744

result:

ok 1 number(s): "672176744"

Test #13:

score: 17
Accepted
time: 0ms
memory: 5144kb

input:

2998

output:

77001108

result:

ok 1 number(s): "77001108"

Test #14:

score: 17
Accepted
time: 3ms
memory: 5076kb

input:

2999

output:

337824775

result:

ok 1 number(s): "337824775"

Test #15:

score: 17
Accepted
time: 3ms
memory: 5088kb

input:

3000

output:

636156660

result:

ok 1 number(s): "636156660"

Subtask #4:

score: 21
Accepted

Dependency #3:

100%
Accepted

Test #16:

score: 21
Accepted
time: 4ms
memory: 5144kb

input:

100000

output:

809175948

result:

ok 1 number(s): "809175948"

Test #17:

score: 21
Accepted
time: 4ms
memory: 5096kb

input:

200000

output:

425311829

result:

ok 1 number(s): "425311829"

Test #18:

score: 21
Accepted
time: 5ms
memory: 5140kb

input:

500000

output:

302623178

result:

ok 1 number(s): "302623178"

Test #19:

score: 21
Accepted
time: 7ms
memory: 5060kb

input:

900000

output:

683174559

result:

ok 1 number(s): "683174559"

Test #20:

score: 21
Accepted
time: 0ms
memory: 5144kb

input:

1000000

output:

126560600

result:

ok 1 number(s): "126560600"

Subtask #5:

score: 22
Accepted

Dependency #4:

100%
Accepted

Test #21:

score: 22
Accepted
time: 106ms
memory: 6032kb

input:

100000000

output:

269652149

result:

ok 1 number(s): "269652149"

Test #22:

score: 22
Accepted
time: 251ms
memory: 6536kb

input:

300000000

output:

421051808

result:

ok 1 number(s): "421051808"

Test #23:

score: 22
Accepted
time: 437ms
memory: 7128kb

input:

700000000

output:

834273337

result:

ok 1 number(s): "834273337"

Test #24:

score: 22
Accepted
time: 560ms
memory: 7144kb

input:

990000000

output:

848544380

result:

ok 1 number(s): "848544380"

Test #25:

score: 22
Accepted
time: 564ms
memory: 7440kb

input:

1000000000

output:

341773916

result:

ok 1 number(s): "341773916"

Subtask #6:

score: 23
Accepted

Dependency #5:

100%
Accepted

Test #26:

score: 23
Accepted
time: 3603ms
memory: 11348kb

input:

12000000000

output:

877921487

result:

ok 1 number(s): "877921487"

Test #27:

score: 23
Accepted
time: 4668ms
memory: 12724kb

input:

17000000000

output:

691116504

result:

ok 1 number(s): "691116504"

Test #28:

score: 23
Accepted
time: 5261ms
memory: 13252kb

input:

19900000000

output:

87007717

result:

ok 1 number(s): "87007717"

Test #29:

score: 23
Accepted
time: 5288ms
memory: 13332kb

input:

19990000000

output:

455948458

result:

ok 1 number(s): "455948458"

Test #30:

score: 23
Accepted
time: 5286ms
memory: 13296kb

input:

20000000000

output:

128153394

result:

ok 1 number(s): "128153394"