Problem p02715 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;
typedef long long LL;
template <typename F, typename S>
std::ostream &operator<<(ostream &os, const pair<F, S> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  for (const T &a : v) {
    os << a << ", ";
  }
  os << "]";
  return os;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  os << "{";
  for (const auto &p : m) {
    os << p.first << ":" << p.second << ", ";
  }
  os << "}";
  return os;
}

// 剰余演算クラス
struct ModInt {
  static const LL MOD = 1e+9 + 7;
  LL v;
  ModInt() : v(0) {}
  ModInt(LL op) : v(op) {}
  ModInt operator+(ModInt op) const { return (v + op) % MOD; }
  ModInt operator-(ModInt op) const { return (v - op + MOD) % MOD; }
  ModInt operator*(ModInt op) const { return (v * op) % MOD; }
  ModInt operator/(ModInt op) const { return (v * op.inverse()) % MOD; }
  ModInt operator%(LL op) = delete;
  ModInt operator+=(ModInt op) { return v = (v + op) % MOD; }
  ModInt operator-=(ModInt op) { return v = (v - op + MOD) % MOD; }
  ModInt operator*=(ModInt op) { return v = (v * op) % MOD; }
  ModInt operator/=(ModInt op) { return v = (v * op.inverse()) % MOD; }
  ModInt operator-() const { return MOD - v; }
  bool operator==(ModInt op) const { return v == op.v; }
  bool operator!=(ModInt op) const { return v != op.v; }
  ModInt inverse() const { return pow(MOD - 2); }
  ModInt pow(LL n) const {
    if (n < 0)
      return pow(MOD - 1 + n);
    if (n == 0)
      return 1;
    ModInt res = pow(n / 2);
    return res * res * ((n & 1) ? ModInt(v) : ModInt(1));
  }
  LL get() const { return v; }

private:
  operator LL() const { return v; }
};
istream &operator>>(istream &st, ModInt &m) {
  st >> m.v;
  return st;
}
ostream &operator<<(ostream &st, const ModInt &m) {
  st << m.v;
  return st;
}

vector<ModInt> factorial(LL n) {
  vector<ModInt> res(n, 1);
  for (LL i = 2; i < n; ++i)
    res[i] = res[i - 1] * ModInt(i);
  return res;
}

ModInt permutation(LL n, LL m, vector<ModInt> &factorial) {
  if (m < 0 || n < m)
    return 0;
  if (m == 0)
    return 1;
  return factorial.at(n) / factorial.at(n - m);
}

ModInt combination(LL n, LL m, vector<ModInt> &factorial) {
  if (m < 0 || n < m)
    return 0;
  if (m == 0)
    return 1;
  return factorial.at(n) / factorial.at(n - m) / factorial.at(m);
}

vector<ModInt> solve(LL n, LL k) {
  if (n == 1) {
    vector<ModInt> res = vector<ModInt>(k + 1, ModInt(1));
    res[0] = ModInt(0);
    return res;
  }
  vector<ModInt> half = solve(n / 2, k);
  vector<ModInt> res(k + 1);
  for (LL v = k; v >= 1; --v) {
    ModInt total = 0;
    for (LL v2 = v; v2 <= k; v2 += v) {
      total += half[v2];
    }
    res[v] = total * total;
    for (LL v2 = v * 2; v2 <= k; v2 += v) {
      res[v] -= res[v2];
    }
  }
  if (n % 2 == 1) {
    vector<ModInt> res2(k + 1);
    for (LL v = k; v >= 1; --v) {
      ModInt total = 0;
      ModInt total2 = 0;
      for (LL v2 = v; v2 <= k; v2 += v) {
        total += res[v2];
        total2 += 1;
      }
      res2[v] = total * total2;
      for (LL v2 = v * 2; v2 <= k; v2 += v) {
        res2[v] -= res2[v2];
      }
    }
    return res2;
  }
  // cerr << "res2=" << res << endl;
  return res;
}

int main() {
  LL n, k;
  cin >> n >> k;
  vector<ModInt> res = solve(n, k);
  // cerr << res << endl;
  ModInt ans = 0;
  for (LL i = 1; i <= k; ++i) {
    ans += res[i] * ModInt(i);
  }
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;
typedef long long LL;
template <typename F, typename S>
std::ostream &operator<<(ostream &os, const pair<F, S> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  for (const T &a : v) {
    os << a << ", ";
  }
  os << "]";
  return os;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  os << "{";
  for (const auto &p : m) {
    os << p.first << ":" << p.second << ", ";
  }
  os << "}";
  return os;
}

// 剰余演算クラス
struct ModInt {
  static const LL MOD = 1e+9 + 7;
  LL v;
  ModInt() : v(0) {}
  ModInt(LL op) : v(op) {}
  ModInt operator+(ModInt op) const { return (v + op) % MOD; }
  ModInt operator-(ModInt op) const { return (v - op + MOD) % MOD; }
  ModInt operator*(ModInt op) const { return (v * op) % MOD; }
  ModInt operator/(ModInt op) const { return (v * op.inverse()) % MOD; }
  ModInt operator%(LL op) = delete;
  ModInt operator+=(ModInt op) { return v = (v + op) % MOD; }
  ModInt operator-=(ModInt op) { return v = (v - op + MOD) % MOD; }
  ModInt operator*=(ModInt op) { return v = (v * op) % MOD; }
  ModInt operator/=(ModInt op) { return v = (v * op.inverse()) % MOD; }
  ModInt operator-() const { return MOD - v; }
  bool operator==(ModInt op) const { return v == op.v; }
  bool operator!=(ModInt op) const { return v != op.v; }
  ModInt inverse() const { return pow(MOD - 2); }
  ModInt pow(LL n) const {
    if (n < 0)
      return pow(MOD - 1 + n);
    if (n == 0)
      return 1;
    ModInt res = pow(n / 2);
    return res * res * ((n & 1) ? ModInt(v) : ModInt(1));
  }
  LL get() const { return v; }

private:
  operator LL() const { return v; }
};
istream &operator>>(istream &st, ModInt &m) {
  st >> m.v;
  return st;
}
ostream &operator<<(ostream &st, const ModInt &m) {
  st << m.v;
  return st;
}

vector<ModInt> factorial(LL n) {
  vector<ModInt> res(n, 1);
  for (LL i = 2; i < n; ++i)
    res[i] = res[i - 1] * ModInt(i);
  return res;
}

ModInt permutation(LL n, LL m, vector<ModInt> &factorial) {
  if (m < 0 || n < m)
    return 0;
  if (m == 0)
    return 1;
  return factorial.at(n) / factorial.at(n - m);
}

ModInt combination(LL n, LL m, vector<ModInt> &factorial) {
  if (m < 0 || n < m)
    return 0;
  if (m == 0)
    return 1;
  return factorial.at(n) / factorial.at(n - m) / factorial.at(m);
}

vector<ModInt> solve(LL n, LL k) {
  if (n == 1) {
    vector<ModInt> res = vector<ModInt>(k + 1, ModInt(1));
    res[0] = ModInt(0);
    return res;
  }
  vector<ModInt> half = solve(n / 2, k);
  vector<ModInt> res(k + 1);
  for (LL v = k; v >= 1; --v) {
    ModInt total = 0;
    for (LL v2 = v; v2 <= k; v2 += v) {
      total += half[v2];
    }
    res[v] = total * total;
    for (LL v2 = v * 2; v2 <= k; v2 += v) {
      res[v] -= res[v2];
    }
  }
  if (n % 2 == 1) {
    vector<ModInt> res2(k + 1);
    for (LL v = k; v >= 1; --v) {
      ModInt total = 0;
      ModInt total2 = 0;
      for (LL v2 = v; v2 <= k; v2 += v) {
        total += res[v2];
        total2 += 1;
      }
      res2[v] = total * total2;
      for (LL v2 = v * 2; v2 <= k; v2 += v) {
        res2[v] -= res2[v2];
      }
    }
    return res2;
  }
  cerr << "res2=" << res << endl;
  return res;
}

int main() {
  LL n, k;
  cin >> n >> k;
  vector<ModInt> res = solve(n, k);
  cerr << res << endl;
  ModInt ans = 0;
  for (LL i = 1; i <= k; ++i) {
    ans += res[i] * ModInt(i);
  }
  cout << ans << endl;
  return 0;
}