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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()
using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
const ll MOD = 1000000007;
const ll INF = 10000000000000000;
vector<int> x4 = {0, 1, 0, -1}, x8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<int> y4 = {1, 0, -1, 0}, y8 = {1, 1, 0, -1, -1, -1, 0, 1};
template <class T> struct edge {
  int from, to;
  T cost;
};
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline T powerM(T a, T b) {
  if (b == 0)
    return 1;
  T tmp = powerM(a, b / 2);
  if (b % 2 == 0)
    return tmp * tmp % MOD;
  else
    return tmp * tmp % MOD * a % MOD;
}
template <class T> inline T power(T a, T b, T m) {
  if (b == 0)
    return 1;
  T tmp = power(a, b / 2, m);
  if (b % 2 == 0)
    return tmp * tmp % m;
  else
    return tmp * tmp % m * a % m;
}
template <class T> inline T gcd(T a, T b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
template <class T> inline T lcm(T a, T b) { return a / gcd(a, b) * b; }
// ax+by=gcd(a,b)を解く
template <class T> inline T extgcd(T a, T b, T &x, T &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  T d = extgcd(b, a % b, y, x);
  y -= a / b * x;
  return d;
}
void chey() { cout << "hey" << endl; }

vector<pair<ll, ll>> pf;
map<ll, ll> dn, dn1;
ll res1 = 0;
ll N;

// 素因数分解O(√n)--------------------------------------------
template <class T> void prime_factor(ll n, map<ll, T> &res) {
  for (ll i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      res[i]++;
      n /= i;
    }
  }
  if (n != 1)
    res[n] += 1;
}

void dfs(ll i, ll endi, ll number) {
  if (i == endi) {
    if (number == 1)
      return;
    // numberが条件を満たすかチェック
    ll tmp = N;
    while (tmp % number == 0)
      tmp /= number;
    tmp %= number;
    if (tmp == 1)
      res1++;
    return;
  }
  for (ll d = 0; d <= pf[i].second; d++) {
    if (d > 0)
      number *= pf[i].first;
    dfs(i + 1, endi, number);
  }
}

int main() {
  cin >> N;
  prime_factor(N - 1, dn1);
  ll res2 = 1;
  for (auto p : dn1) {
    res2 *= p.second + 1;
  }
  res2--; // N-1を素因数分解して得られる約数。最初から引き算のやつ

  prime_factor(N, dn);
  pf.assign(dn.size(), {0, 0});
  ll tmpi = 0;
  for (auto p : dn) {
    pf[tmpi++] = {p.first, p.second};
  }
  // pf[i]...素因数i個目。{a,b}...a^b
  // vector<ll> pfnum(dn.size());
  dfs(0, dn.size(), 1);
  ll res = res1 + res2;
  cout << res << endl;
}

// N = K か N = K+1 になれば最終的に1になる
// N = N/K を行ってKの倍数 → Kの倍数でない、となることはある
// N = N-K を行ってKの倍数でない → Kの倍数、となることはない
/*
  N = K となるのは N が K のべき乗で表されるとき(Kで割りまくってKになる)
  N = K+1 となるのは色々あるが途中絶対に N-1 が K の倍数になる
*/
/*
// N-1を素因数分解して得られる約数全て(1以外)は条件を満たす
// じゃあ１回はkで割れるやつらはどうだろう

Nを素因数分解して得られる
*/
/*
1 K   K^2    K^3
  K+1 (K+1)K (K+1)K^2
      2K+1   (2K+1)K
             3K+1

*/


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()
using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
const ll MOD = 1000000007;
const ll INF = 10000000000000000;
vector<int> x4 = {0, 1, 0, -1}, x8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<int> y4 = {1, 0, -1, 0}, y8 = {1, 1, 0, -1, -1, -1, 0, 1};
template <class T> struct edge {
  int from, to;
  T cost;
};
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline T powerM(T a, T b) {
  if (b == 0)
    return 1;
  T tmp = powerM(a, b / 2);
  if (b % 2 == 0)
    return tmp * tmp % MOD;
  else
    return tmp * tmp % MOD * a % MOD;
}
template <class T> inline T power(T a, T b, T m) {
  if (b == 0)
    return 1;
  T tmp = power(a, b / 2, m);
  if (b % 2 == 0)
    return tmp * tmp % m;
  else
    return tmp * tmp % m * a % m;
}
template <class T> inline T gcd(T a, T b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
template <class T> inline T lcm(T a, T b) { return a / gcd(a, b) * b; }
// ax+by=gcd(a,b)を解く
template <class T> inline T extgcd(T a, T b, T &x, T &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  T d = extgcd(b, a % b, y, x);
  y -= a / b * x;
  return d;
}
void chey() { cout << "hey" << endl; }

vector<pair<int, int>> pf;
map<int, int> dn, dn1;
ll res1 = 0;
ll N;

// 素因数分解O(√n)--------------------------------------------
template <class T> void prime_factor(int n, map<int, T> &res) {
  for (int i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      res[i]++;
      n /= i;
    }
  }
  if (n != 1)
    res[n] += 1;
}

void dfs(int i, int endi, ll number) {
  if (i == endi) {
    if (number == 1)
      return;
    // numberが条件を満たすかチェック
    ll tmp = N;
    while (tmp % number == 0)
      tmp /= number;
    tmp %= number;
    if (tmp == 1)
      res1++;
    return;
  }
  for (int d = 0; d <= pf[i].second; d++) {
    if (d > 0)
      number *= pf[i].first;
    dfs(i + 1, endi, number);
  }
}

int main() {
  cin >> N;
  ll test = N;
  int tmpres = 0;
  for (ll i = 2; i <= test; i++) {
    ll tmp = test;
    while (tmp % i == 0)
      tmp /= i;
    if (tmp % i == 1)
      tmpres++;
  }
  cout << tmpres << endl;
}

// N = K か N = K+1 になれば最終的に1になる
// N = N/K を行ってKの倍数 → Kの倍数でない、となることはある
// N = N-K を行ってKの倍数でない → Kの倍数、となることはない
/*
  N = K となるのは N が K のべき乗で表されるとき(Kで割りまくってKになる)
  N = K+1 となるのは色々あるが途中絶対に N-1 が K の倍数になる
*/
/*
// N-1を素因数分解して得られる約数全て(1以外)は条件を満たす
// じゃあ１回はkで割れるやつらはどうだろう
N = 2^3 * 3^2 = 72とかとする
K = 2...9, o
K = 3...8, x
K = 4...18, x
K = 6...2, x
K = 8...9, o
K = 9...8, x
K = 12...6, x
K = 18...4, x
K = 24...3, x
K = 36...2, x

Nを素因数分解して得られる
*/
/*
1 K   K^2    K^3
  K+1 (K+1)K (K+1)K^2
      2K+1   (2K+1)K
             3K+1

*/