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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
ll gcd(ll a, ll b) { return __gcd(a, b); }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll mod = 15;

ll add(ll a, ll b) { return (a + b) % mod; }

ll mul(ll a, ll b) { return (a * b) % mod; }

ll mod_pow(ll a, ll b) {
  if (b == 0)
    return 1;
  ll res = mod_pow(mul(a, a), b / 2);
  if (b & 1)
    res = mul(res, a);
  return res;
}

ll euler(ll n) {
  ll res = n;
  for (ll i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      res = res / i * (i - 1);
      while (n % i == 0)
        n /= i;
    }
  }
  if (n != 1)
    res = res / n * (n - 1);
  return res;
}

bool isP(ll x) {
  for (ll i = 2; i * i <= x; i++) {
    if (x % i == 0)
      return false;
  }
  return (x >= 2);
}

ll solve(ll a, ll b) {
  ll cnt = 0, k = a;
  while (1) {
    k = (k * a) % b;
    cnt++;
    if (k == a) {
      break;
    }

    if (cnt > 1e8) {
      cnt = euler(b);
      break;
    }
  }
  return cnt;
}

int main() {
  ll n;
  cin >> n;

  if (isP(n)) {
    cout << 1 << endl;
    return 0;
  }

  vector<ll> s;

  for (ll i = 2; i * i <= n; i++) {
    if (n % (i * i) == 0) {
      cout << -1 << endl;
      return 0;
    }
    if (n % i == 0) {
      s.push_back(i);
      s.push_back(n / i);
    }
  }
  ll ans = 1;

  for (int i = 0; i < (int)s.size(); i++) {
    ll num = euler(n / s[i]);
    ans = lcm(ans, num);
  }

  if (n % ans == 0 || __gcd(n, ans) != 1) {
    cout << -1 << endl;
    return 0;
  }

  ll k = 1, cnt = 0;
  while (1) {
    k = (k * n) % ans;
    cnt++;
    if (k == 1) {
      break;
    }
    if (cnt > 1e8) {
      cnt = euler(ans);
      break;
    }
  }
  cout << cnt << endl;

  /*
  ll C=1;
  for(ll i=0;i<n;i++){
    ll k=solve( i , n );
    C=lcm(k,C);
  }
  */
  //  cout<<C<<' '<<ans<<endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
ll gcd(ll a, ll b) { return __gcd(a, b); }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll mod = 15;

ll add(ll a, ll b) { return (a + b) % mod; }

ll mul(ll a, ll b) { return (a * b) % mod; }

ll mod_pow(ll a, ll b) {
  if (b == 0)
    return 1;
  ll res = mod_pow(mul(a, a), b / 2);
  if (b & 1)
    res = mul(res, a);
  return res;
}

ll euler(ll n) {
  ll res = n;
  for (ll i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      res = res / i * (i - 1);
      while (n % i == 0)
        n /= i;
    }
  }
  if (n != 1)
    res = res / n * (n - 1);
  return res;
}

bool isP(ll x) {
  for (ll i = 2; i * i <= x; i++) {
    if (x % i == 0)
      return false;
  }
  return (x >= 2);
}

ll solve(ll a, ll b) {
  ll cnt = 0, k = a;
  while (1) {
    k = (k * a) % b;
    cnt++;
    if (k == a) {
      break;
    }

    if (cnt > 1e6) {
      cnt = b - 1;
      break;
    }
  }
  return cnt;
}

int main() {
  ll n;
  cin >> n;

  if (isP(n)) {
    cout << 1 << endl;
    return 0;
  }

  vector<ll> s;

  for (ll i = 2; i * i <= n; i++) {
    if (n % (i * i) == 0) {
      cout << -1 << endl;
      return 0;
    }
    if (n % i == 0) {
      s.push_back(i);
      s.push_back(n / i);
    }
  }
  ll ans = 1;

  for (int i = 0; i < (int)s.size(); i++) {
    ans = lcm(ans, solve(s[i], n));
  }

  ans = lcm(ans, euler(n));

  if (n % ans == 0 || __gcd(n, ans) != 1) {
    cout << -1 << endl;
    return 0;
  }

  ll k = 1, cnt = 0;
  while (1) {
    k = (k * n) % ans;
    cnt++;
    if (k == 1) {
      break;
    }
    if (cnt > 1e7) {
      cnt = euler(ans);
      break;
    }
  }
  cout << cnt << endl;

  ll C = 1;
  for (ll i = 0; i < n; i++) {
    ll k = solve(i, n);
    C = lcm(k, C);
  }
  //  cout<<C<<' '<<ans<<endl;

  return 0;
}