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

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL

int xgcd(int, int, int &, int &);
int gcd(int, int);
int modinv(int, int);
ll modInverse(ll, ll);
ll power(ll, ll, ll);

ll pow2(int);

int N;

// 素数判定
#define MAX_PRIME 1000
vector<int> pr = {2, 3, 5, 7};

bool isprime(int n) {
  int i;
  int prime(int);
  if (n > MAX_PRIME)
    return true;
  int sz = pr.size();
  int sq = sqrt(n);
  for (i = 1; i < sz; i++) {
    int p = pr[i];
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
  for (;; i++) {
    int p = prime(i);
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
}

// 素数生成
int prime(int n) {
  int last = pr.size();
  if (n < last)
    return pr[n];

  for (int p = pr.back() + 2; last <= n; p += 2) {
    if (isprime(p)) {
      last++;
      pr.push_back(p);
    }
  }
  return pr.back();
}

// 素因数分解
// 引数の整数を素因数分解する。
// mapクラスのキーに基数、対応する値に指数が入っている
map<ll, int> lc;
map<ll, int> fact(ll n) {
  map<ll, int> ret;
  ll base;
  int ix;

  int i;
  for (i = 0; n > 1; i++) {
    base = prime(i);
    ix = 0;
    while (n % base == 0) {
      ix++;
      n /= base;
    }
    if (ix > 0) {
      ret[base] = ix;
      auto itr = lc.find(base);
      if (itr == lc.end()) {
        lc[base] = ix;
      } else {
        lc[base] = max(ix, lc[base]);
      }
    } else {
      if (base * base >= n) {
        ret[n] = 1;
        auto itr = lc.find(n);
        if (itr == lc.end()) {
          lc[n] = 1;
        } else {
          lc[n] = max(1, lc[n]);
        }
        break;
      }
    }
  }
  return ret;
}

// 最大公約数
// 素因数分解された値での最大公約数算出
map<int, int> lcm(map<int, int> m, map<int, int> n) {
  map<int, int> ret;

  for (auto itm = m.begin(); itm != m.end(); itm++) {
    auto itn = n.find(itm->first);
    if (itn == n.end()) {
      ret[itm->first] = itm->second;
    } else {
      ret[itm->first] = max(itm->second, itn->second);
      n.erase(itm->first);
    }
  }
  for (auto itn = n.begin(); itn != n.end(); itn++) {
    ret[itn->first] = itn->second;
  }

  return ret;
}

// 除算
//  素因数分解された値の除算
map<int, int> vdiv(map<int, int> m, map<int, int> n) {
  map<int, int> ret;

  for (auto itm = m.begin(); itm != m.end(); itm++) {
    auto itn = n.find(itm->first);
    if (itn == n.end()) {
      ret[itm->first] = itm->second;
    } else {
      ret[itm->first] = itm->second - itn->second;
      n.erase(itm->first);
    }
  }
  for (auto itn = n.begin(); itn != n.end(); itn++) {
    ret[itn->first] = -itn->second;
  }
  return ret;
}
// modの剰余として、素因数分解したものをint型に変換する
int toInt(map<int, int> f, int m) {
  ll lret = 1;

  for (auto itr = f.begin(); itr != f.end(); itr++) {
    for (int j = 0; j < itr->second; j++) {
      lret *= itr->first;
      lret %= m;
    }
  }
  return lret;
}

// 最大公約数 ユークリッド互除法
int gcd(int m, int n) {
  if (m < n)
    swap(m, n);
  while (m % n) {
    m %= n;
    swap(m, n);
  }
  return n;
}
// 最大公約数 拡張ユークリッド互除法
int xgcd(int a, int b, int &x0, int &y0) {
  x0 = 1, y0 = 0;
  int x1 = 0, y1 = 1;
  int q;
  int at, x0t, y0t;
  while (b != 0) {
    q = a / b;
    at = b;
    b = a % b;
    a = at;
    x0t = x1;
    x1 = x0 - q * x1;
    x0 = x0t;
    y0t = y1;
    y1 = y0 - q * y1;
    y0 = y0t;
  }
  return a;
}
ll xgcd(ll a, ll b, ll &x0, ll &y0) {
  x0 = 1, y0 = 0;
  ll x1 = 0, y1 = 1;
  ll q;
  ll at, x0t, y0t;
  while (b != 0) {
    q = a / b;
    at = b;
    b = a % b;
    a = at;
    x0t = x1;
    x1 = x0 - q * x1;
    x0 = x0t;
    y0t = y1;
    y1 = y0 - q * y1;
    y0 = y0t;
  }
  return a;
}
// モジュラー逆数
//((ab mod n)(b^-1 mod n)) mod n = a mod n となる aを求めるのに使う
// ab mod n と b mod nがわかっているときに a mod n を算出するため
// modInverseは実績ありmodinvは不明
int modinv(int a, int m) {
  int g, x, y;
  g = xgcd(a, m, x, y);
  if (g != 1)
    return -1;
  x %= m;
  if (x < 0)
    x += m;
  return x;
}
ll modinv(ll a, ll m) {
  ll g, x, y;
  g = xgcd(a, m, x, y);
  if (g != 1)
    return -1;
  x %= m;
  if (x < 0)
    x += m;
  return x;
}
ll power(ll x, ll y, ll p) {
  ll res = 1;
  x = x % p;
  while (y > 0) {
    if (y & 1)
      res = (res * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return res;
}
ll modInverse(ll a, ll m) {
  ll ans = power(a, m - 2, m);
  return ans;
}

ll pow2(int n) {
  ll ret = 1;
  ll r2 = 2;
  int i;

  for (i = n; i > 0; i /= 2) {
    if (i % 2)
      ret *= r2;
    ret %= MOD;
    r2 *= r2;
    r2 %= MOD;
  }
  return ret;
}

// multimap<ll, int> pmap;
map<int, int> pmap;
set<ll> pl;

int main() {
  /*
  for (int i=0; i<20; i++) {
    printf("%d\\n", prime(i));
  }
    */
  // printf("%d\\n", prime(200));
  prime(200);

  cin >> N;
  for (int i = 0; i < N; i++) {
    int ain;
    cin >> ain;
    // printf("%d =", ain);
    for (int j = 0;; j++) {
      int px = pr[j];
      if (ain % px == 0) {
        //        pmap.emplace(px, i);
        if (pmap.count(px) == 0) {
          pmap[px] = 1;
        } else {
          pmap[px] = pmap[px] + 1;
        }
        pl.insert(px);
        ain /= px;
        // printf(" %d", px);
      }
      while (ain % px == 0)
        ain /= px;
      if (ain < px * px)
        break;
    }
    if (ain != 1) {
      //      pmap.emplace(ain, i);
      if (pmap.count(ain) == 0) {
        pmap[ain] = 1;
      } else {
        pmap[ain] = pmap[ain] + 1;
      }
      pl.insert(ain);
      // printf(" %d", ain);
    }
    // printf("\\n");
  }

  bool ispc, issc;
  ispc = true;
  issc = true;

  for (auto it = pl.begin(); it != pl.end(); it++) {
    // printf("%lld :", *it);
    if (pmap[*it] > 1)
      ispc = false;
    if ((int)pmap[*it] == N)
      issc = false;
  }

  if (ispc) {
    printf("pairwise coprime\\n");
    return 0;
  }
  if (issc) {
    printf("setwise coprime\\n");
    return 0;
  }

  printf("not coprime\\n");

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL

int xgcd(int, int, int &, int &);
int gcd(int, int);
int modinv(int, int);
ll modInverse(ll, ll);
ll power(ll, ll, ll);

ll pow2(int);

int N;

// 素数判定
#define MAX_PRIME 1000
vector<int> pr = {2, 3, 5, 7};

bool isprime(int n) {
  int i;
  int prime(int);
  if (n > MAX_PRIME)
    return true;
  int sz = pr.size();
  int sq = sqrt(n);
  for (i = 1; i < sz; i++) {
    int p = pr[i];
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
  for (;; i++) {
    int p = prime(i);
    if (p > sq)
      return true;
    if (n % p == 0)
      return false;
  }
}

// 素数生成
int prime(int n) {
  int last = pr.size();
  if (n < last)
    return pr[n];

  for (int p = pr.back() + 2; last <= n; p += 2) {
    if (isprime(p)) {
      last++;
      pr.push_back(p);
    }
  }
  return pr.back();
}

// 素因数分解
// 引数の整数を素因数分解する。
// mapクラスのキーに基数、対応する値に指数が入っている
map<ll, int> lc;
map<ll, int> fact(ll n) {
  map<ll, int> ret;
  ll base;
  int ix;

  int i;
  for (i = 0; n > 1; i++) {
    base = prime(i);
    ix = 0;
    while (n % base == 0) {
      ix++;
      n /= base;
    }
    if (ix > 0) {
      ret[base] = ix;
      auto itr = lc.find(base);
      if (itr == lc.end()) {
        lc[base] = ix;
      } else {
        lc[base] = max(ix, lc[base]);
      }
    } else {
      if (base * base >= n) {
        ret[n] = 1;
        auto itr = lc.find(n);
        if (itr == lc.end()) {
          lc[n] = 1;
        } else {
          lc[n] = max(1, lc[n]);
        }
        break;
      }
    }
  }
  return ret;
}

// 最大公約数
// 素因数分解された値での最大公約数算出
map<int, int> lcm(map<int, int> m, map<int, int> n) {
  map<int, int> ret;

  for (auto itm = m.begin(); itm != m.end(); itm++) {
    auto itn = n.find(itm->first);
    if (itn == n.end()) {
      ret[itm->first] = itm->second;
    } else {
      ret[itm->first] = max(itm->second, itn->second);
      n.erase(itm->first);
    }
  }
  for (auto itn = n.begin(); itn != n.end(); itn++) {
    ret[itn->first] = itn->second;
  }

  return ret;
}

// 除算
//  素因数分解された値の除算
map<int, int> vdiv(map<int, int> m, map<int, int> n) {
  map<int, int> ret;

  for (auto itm = m.begin(); itm != m.end(); itm++) {
    auto itn = n.find(itm->first);
    if (itn == n.end()) {
      ret[itm->first] = itm->second;
    } else {
      ret[itm->first] = itm->second - itn->second;
      n.erase(itm->first);
    }
  }
  for (auto itn = n.begin(); itn != n.end(); itn++) {
    ret[itn->first] = -itn->second;
  }
  return ret;
}
// modの剰余として、素因数分解したものをint型に変換する
int toInt(map<int, int> f, int m) {
  ll lret = 1;

  for (auto itr = f.begin(); itr != f.end(); itr++) {
    for (int j = 0; j < itr->second; j++) {
      lret *= itr->first;
      lret %= m;
    }
  }
  return lret;
}

// 最大公約数 ユークリッド互除法
int gcd(int m, int n) {
  if (m < n)
    swap(m, n);
  while (m % n) {
    m %= n;
    swap(m, n);
  }
  return n;
}
// 最大公約数 拡張ユークリッド互除法
int xgcd(int a, int b, int &x0, int &y0) {
  x0 = 1, y0 = 0;
  int x1 = 0, y1 = 1;
  int q;
  int at, x0t, y0t;
  while (b != 0) {
    q = a / b;
    at = b;
    b = a % b;
    a = at;
    x0t = x1;
    x1 = x0 - q * x1;
    x0 = x0t;
    y0t = y1;
    y1 = y0 - q * y1;
    y0 = y0t;
  }
  return a;
}
ll xgcd(ll a, ll b, ll &x0, ll &y0) {
  x0 = 1, y0 = 0;
  ll x1 = 0, y1 = 1;
  ll q;
  ll at, x0t, y0t;
  while (b != 0) {
    q = a / b;
    at = b;
    b = a % b;
    a = at;
    x0t = x1;
    x1 = x0 - q * x1;
    x0 = x0t;
    y0t = y1;
    y1 = y0 - q * y1;
    y0 = y0t;
  }
  return a;
}
// モジュラー逆数
//((ab mod n)(b^-1 mod n)) mod n = a mod n となる aを求めるのに使う
// ab mod n と b mod nがわかっているときに a mod n を算出するため
// modInverseは実績ありmodinvは不明
int modinv(int a, int m) {
  int g, x, y;
  g = xgcd(a, m, x, y);
  if (g != 1)
    return -1;
  x %= m;
  if (x < 0)
    x += m;
  return x;
}
ll modinv(ll a, ll m) {
  ll g, x, y;
  g = xgcd(a, m, x, y);
  if (g != 1)
    return -1;
  x %= m;
  if (x < 0)
    x += m;
  return x;
}
ll power(ll x, ll y, ll p) {
  ll res = 1;
  x = x % p;
  while (y > 0) {
    if (y & 1)
      res = (res * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return res;
}
ll modInverse(ll a, ll m) {
  ll ans = power(a, m - 2, m);
  return ans;
}

ll pow2(int n) {
  ll ret = 1;
  ll r2 = 2;
  int i;

  for (i = n; i > 0; i /= 2) {
    if (i % 2)
      ret *= r2;
    ret %= MOD;
    r2 *= r2;
    r2 %= MOD;
  }
  return ret;
}

multimap<ll, int> pmap;
set<ll> pl;

int main() {
  /*
  for (int i=0; i<20; i++) {
    printf("%d\\n", prime(i));
  }
    */
  // printf("%d\\n", prime(170));
  prime(170);

  cin >> N;
  for (int i = 0; i < N; i++) {
    int ain;
    cin >> ain;
    // printf("%d =", ain);
    for (int j = 0;; j++) {
      int px = pr[j];
      if (ain % px == 0) {
        pmap.emplace(px, i);
        pl.insert(px);
        ain /= px;
        // printf(" %d", px);
      }
      while (ain % px == 0)
        ain /= px;
      if (ain < px * px)
        break;
    }
    if (ain != 1) {
      pmap.emplace(ain, i);
      pl.insert(ain);
      // printf(" %d", ain);
    }
    // printf("\\n");
  }

  bool ispc, issc;
  ispc = true;
  issc = true;

  for (auto it = pl.begin(); it != pl.end(); it++) {
    // printf("%lld :", *it);
    if (pmap.count(*it) > 1)
      ispc = false;
    if ((int)pmap.count(*it) == N)
      issc = false;
    /*
    auto p = pmap.equal_range(*it);
    for (auto pit=p.first; pit != p.second; pit++) {
printf(" %d", pit->second);
    }
    printf("\\n");
      */
  }

  if (ispc) {
    printf("pairwise coprime\\n");
    return 0;
  }
  if (issc) {
    printf("setwise coprime\\n");
    return 0;
  }

  printf("not coprime\\n");

  return 0;
}