Problem p03867 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define REP(i, st, ed) for (register int i = st, i##end = ed; i <= i##end; ++i)
#define DREP(i, st, ed) for (register int i = st, i##end = ed; i >= i##end; --i)
typedef long long ll;
template <typename T> inline bool chkmin(T &x, T y) {
  return (y < x) ? (x = y, 1) : 0;
}
template <typename T> inline bool chkmax(T &x, T y) {
  return (y > x) ? (x = y, 1) : 0;
}
inline int read() {
  int x;
  char c;
  int f = 1;
  while ((c = getchar()) != '-' && (c > '9' || c < '0'))
    ;
  if (c == '-')
    f = -1, c = getchar();
  x = c ^ '0';
  while ((c = getchar()) >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + (c ^ '0');
  return x * f;
}
inline ll readll() {
  ll x;
  char c;
  int f = 1;
  while ((c = getchar()) != '-' && (c > '9' || c < '0'))
    ;
  if (c == '-')
    f = -1, c = getchar();
  x = c ^ '0';
  while ((c = getchar()) >= '0' && c <= '9')
    x = (x << 1ll) + (x << 3ll) + (c ^ '0');
  return x * f;
}
const int maxn = 2e3 + 10, mod = 1e9 + 7;
int f[maxn], num[maxn], tmp;
inline int ksm(int x, int y) {
  int res = 1;
  while (y) {
    if (y & 1)
      res = (ll)res * x % mod;
    x = (ll)x * x % mod;
    y >>= 1;
  }
  return res;
}
int main() {
#ifndef ONLINE_JUDGE
  freopen("f.in", "r", stdin);
  freopen("f.out", "w", stdout);
#endif
  int n = read(), m = read();
  for (int i = 1; (ll)i * i <= n; ++i)
    if (n % i == 0) {
      num[++tmp] = i;
      if (i * i != n)
        num[++tmp] = n / i;
    }
  sort(num + 1, num + tmp + 1);
  int ans = 0;
  REP(i, 1, tmp) {
    f[i] = (f[i] + ksm(m, (num[i] + 1) / 2)) % mod;
    REP(j, i + 1, tmp)
    if (num[j] % num[i] == 0) f[j] = (f[j] + mod - f[i]) % mod;
    ans =
        (ans + (ll)f[i] * num[i] % mod * ((num[i] & 1) ? 1 : ((mod + 1) / 2))) %
        mod;
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define REP(i, st, ed) for (register int i = st, i##end = ed; i <= i##end; ++i)
#define DREP(i, st, ed) for (register int i = st, i##end = ed; i >= i##end; --i)
typedef long long ll;
template <typename T> inline bool chkmin(T &x, T y) {
  return (y < x) ? (x = y, 1) : 0;
}
template <typename T> inline bool chkmax(T &x, T y) {
  return (y > x) ? (x = y, 1) : 0;
}
inline int read() {
  int x;
  char c;
  int f = 1;
  while ((c = getchar()) != '-' && (c > '9' || c < '0'))
    ;
  if (c == '-')
    f = -1, c = getchar();
  x = c ^ '0';
  while ((c = getchar()) >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + (c ^ '0');
  return x * f;
}
inline ll readll() {
  ll x;
  char c;
  int f = 1;
  while ((c = getchar()) != '-' && (c > '9' || c < '0'))
    ;
  if (c == '-')
    f = -1, c = getchar();
  x = c ^ '0';
  while ((c = getchar()) >= '0' && c <= '9')
    x = (x << 1ll) + (x << 3ll) + (c ^ '0');
  return x * f;
}
const int maxn = 2e3 + 10, mod = 1e9 + 7;
int f[maxn], num[maxn], tmp;
inline int ksm(int x, int y) {
  int res = 1;
  while (y) {
    if (y & 1)
      res = (ll)res * x % mod;
    x = (ll)x * x % mod;
    y >>= 1;
  }
  return res;
}
int main() {
  int n = read(), m = read();
  for (int i = 1; (ll)i * i <= n; ++i)
    if (n % i == 0) {
      num[++tmp] = i;
      if (i * i != n)
        num[++tmp] = n / i;
    }
  sort(num + 1, num + tmp + 1);
  int ans = 0;
  REP(i, 1, tmp) {
    f[i] = (f[i] + ksm(m, (num[i] + 1) / 2)) % mod;
    REP(j, i + 1, tmp)
    if (num[j] % num[i] == 0) f[j] = (f[j] + mod - f[i]) % mod;
    ans =
        (ans + (ll)f[i] * num[i] % mod * ((num[i] & 1) ? 1 : ((mod + 1) / 2))) %
        mod;
  }
  printf("%d\n", ans);
  return 0;
}