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

// ba mei zi !

#include <bits/stdc++.h>

#define HEAP priority_queue
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define per(i, n) for (int i = (n)-1; i >= 0; --i)
#define forn(i, l, r) for (int i = (l); i <= (r); ++i)
#define nrof(i, r, l) for (int i = (r); i >= (l); --i)
#define FOR(a, b) for (auto(a) : (b))
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define X first
#define Y second
#define eps 1e-6
#define pi 3.1415926535897932384626433832795
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(), x.end()
#define FILL(a, b) memset((a), (b), sizeof((a)))
#define MCPY(a, b) memcpy((a), (b), sizeof((b)))

using namespace std;

typedef long long LL;
typedef double flt;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef pair<int, int> pii;
typedef pair<int, LL> pil;
typedef pair<LL, int> pli;
typedef pair<LL, LL> pll;
typedef vector<pil> vil;
typedef vector<pii> vii;
typedef vector<pli> vli;
typedef vector<pll> vll;

const int iinf = 1e9 + 7;
const LL linf = 1ll << 60;
const flt dinf = 1e60;

template <typename T> inline void scf(T &x) {
  bool f = 0;
  x = 0;
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-')
    c = getchar();
  if (c == '-') {
    f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  if (f)
    x = -x;
  return;
}

template <typename T1, typename T2> void scf(T1 &x, T2 &y) {
  scf(x);
  return scf(y);
}

template <typename T1, typename T2, typename T3> void scf(T1 &x, T2 &y, T3 &z) {
  scf(x);
  scf(y);
  return scf(z);
}

template <typename T1, typename T2, typename T3, typename T4>
void scf(T1 &x, T2 &y, T3 &z, T4 &w) {
  scf(x);
  scf(y);
  scf(z);
  return scf(w);
}

inline char mygetchar() {
  char c = getchar();
  while (c == ' ' || c == '\\n')
    c = getchar();
  return c;
}

template <typename T> void chkmax(T &x, const T &y) {
  if (y > x)
    x = y;
  return;
}

template <typename T> void chkmin(T &x, const T &y) {
  if (y < x)
    x = y;
  return;
}

#ifdef ONLINE_JUDGE
#define debug(x, c) ;
#else
#define DEBUG
#define debug(x, c) cerr << #x << "=" << x << c;
#endif

//---------------------------head----------------------------

const int N = 1e3 + 100;
const int mod = 1e9 + 7;

int n, diameter_length, min_D;
int dp[N][N], tag[N][N], current_time;
vi g[N];
vi diameter_path;

namespace TREE {
int par[N], dep[N];

void dfs(int u = 1, int fa = 0) {
  par[u] = fa;
  dep[u] = dep[fa] + 1;
  for (int v : g[u])
    if (v != fa)
      dfs(v, u);
  return;
}

void get_diameter() {
  dfs();
  int mx = -1, S, T;
  forn(i, 1, n) if (dep[i] > mx) mx = dep[i], S = i;
  dfs(S);
  mx = -1;
  forn(i, 1, n) if (dep[i] > mx) mx = dep[i], T = i;

  diameter_length = dep[T] - 1;
  min_D = dep[T] >> 1;

  int u = T;
  while (u != S)
    diameter_path.pb(u), u = par[u];
  diameter_path.pb(S);
  return;
}
} // namespace TREE

void MEI() {
  scf(n);
  rep(i, n - 1) {
    int u, v;
    scf(u, v);
    g[u].pb(v);
    g[v].pb(u);
  }

  TREE::get_diameter();
  return;
}

namespace Bamboo {
void solve() {
  dp[0][0] = 1;
  forn(i, 1, n - 1) {
    dp[i][0] = dp[i][i] = 1;
    forn(j, 1, i - 1) dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
  }
  printf("%d\\n", (n & 1) ? dp[n - 1][min_D] : (dp[n - 1][min_D] * 2 % mod));
  return;
}
} // namespace Bamboo

void DP(int u, int par, int max_down, int max_up) {
  if (tag[u][max_down] == current_time)
    return;

  tag[u][max_down] = current_time;
  int &t = dp[u][max_down];
  t = 1;

  for (int v : g[u])
    if (v != par) {
      int foo = 0;
      if (max_down)
        DP(v, u, max_down - 1, max_up), foo += dp[v][max_down - 1];
      if (max_up)
        DP(v, u, max_down, max_up - 1), foo += dp[v][max_down];
      t = 1ll * t * foo % mod;
    }
  return;
}

namespace Odd {
int ans = 0;
int root1, root2;

void case1() {
  rep(down2, min_D) {
    int up1 = min_D - 1 - down2;
    int up2 = up1, down1 = down2;

    current_time++;
    DP(root2, root1, down2, up2);
    int foo = dp[root2][down2];

    current_time++;
    DP(root1, root2, down1, up1);
    foo = 1ll * foo * dp[root1][down1] % mod;
    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void case2() {
  forn(down2, 1, min_D - 1) {
    int up2 = min_D - 1 - down2;
    int up1 = min_D - down2;
    int down1 = min_D - 1 - up1;

    current_time++;
    DP(root2, root1, down2, up2);
    int foo = dp[root2][down2];

    current_time++;
    DP(root1, root2, down1, up1);
    foo = 1ll * foo * dp[root1][down1] % mod;
    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void case3() {
  rep(down2, min_D) {
    int up1 = min_D - down2;
    int up2 = up1 - 1;
    int down1 = min_D - up1;

    current_time++;
    DP(root2, root1, down2, up2);
    int foo = dp[root2][down2];

    current_time++;
    DP(root1, root2, down1, up1);
    LL bar = dp[root1][down1];
    if (down1 > 0) {
      current_time++;
      DP(root1, root2, down1 - 1, up1);
      bar += mod - dp[root1][down1 - 1];
    }
    if (up1 > 0) {
      current_time++;
      DP(root1, root2, down1, up1 - 1);
      bar += mod - dp[root1][down1];
    }

    foo = 1ll * foo * bar % mod;
    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void case4() {
  forn(down2, 1, min_D) {
    int up1 = min_D - down2;
    int up2 = up1;
    int down1 = min_D - 1 - up1;

    current_time++;
    DP(root2, root1, down2, up2);
    LL foo = dp[root2][down2];
    if (up2 > 0) {
      current_time++;
      DP(root2, root1, down2, up2 - 1);
      foo += mod - dp[root2][down2];
    }
    if (down2 > 0) {
      current_time++;
      DP(root2, root1, down2 - 1, up2);
      foo += mod - dp[root2][down2 - 1];
    }

    current_time++;
    DP(root1, root2, down1, up1);
    foo = foo * 1ll * dp[root1][down1] % mod;

    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void solve() {
  root1 = diameter_path[min_D - 1];
  root2 = diameter_path[min_D];
  case1();
  case2();
  case3();
  case4();
  ans += ans;
  if (ans >= mod)
    ans -= mod;
  printf("%d\\n", ans);
  return;
}
} // namespace Odd

namespace Even {
void solve() {
  int root = diameter_path[min_D];
  int ans = 0;
  forn(max_down, 0, min_D) {
    current_time++;
    DP(root, 0, max_down, min_D - max_down);
    ans += dp[root][max_down];
    if (ans >= mod)
      ans -= mod;
  }
  printf("%d\\n", ans);
  return;
}
} // namespace Even

void ZI() {
  if (diameter_length == n - 1)
    Bamboo::solve();
  else if (diameter_length & 1)
    Odd::solve();
  else
    Even::solve();
  return;
}

/*
   Main
   code
   is
   over
   .
   If
   you
   are
   in
   a
   hurry
   trying
   to
   hack
   me
   you
   don't
   need
   to
   read
   the
   part
   left
   .
   Trust
   me
   .
   It
   is
   useless
   .
   My
   code
   always
gets
a
failed
system
test
,
so
it
will
be
pretty
easy
for
you
to
hack
me
.
Just
find
a
test
case
and
hack
.
Wish
you
all
happy
hack
.
 _____
/     \\
| . . |
|     |
|  |  |
| --- |
| \\_/ |
\\_____/

*/

#ifdef DEBUG

struct I {
  int x;
  I() {}
  I(int y) : x(y) {}
  bool operator<(const I &a) const { return x < a.x; }
};

pair<I, LL> time_limit_exceeded;
const bool FLAG = 1;
static vector<I> wrong_answer;
I *RP = new I;

I FUCK = min(I{*RP}, I{0});
static int memory_limit_exceeded[10];
vi O() {
  cout << FUCK.x << endl;
  vi ert;
  int x = 0;
  x = (int)hypot(3.0, 4.0);
  ert.pb(x);
  if (x & 1)
    exit(0);
  auto t = lower_bound(ALL(ert), 5);
  static list<int> runtime_error_;
  return ert;
}
#endif // DEBUG

#define MEI int
#define ZI main
MEI ZI() {
#undef MEI
#undef ZI

  MEI();
  ZI();

#define BA return
#define MEI 0
#define ZI ;
  BA MEI ZI
#undef BA
#undef MEI
#undef ZI
}

Error: TLE

Fixed submission:

// ba mei zi !

#include <bits/stdc++.h>

#define HEAP priority_queue
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define per(i, n) for (int i = (n)-1; i >= 0; --i)
#define forn(i, l, r) for (int i = (l); i <= (r); ++i)
#define nrof(i, r, l) for (int i = (r); i >= (l); --i)
#define FOR(a, b) for (auto(a) : (b))
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define X first
#define Y second
#define eps 1e-6
#define pi 3.1415926535897932384626433832795
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(), x.end()
#define FILL(a, b) memset((a), (b), sizeof((a)))
#define MCPY(a, b) memcpy((a), (b), sizeof((b)))

using namespace std;

typedef long long LL;
typedef double flt;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef pair<int, int> pii;
typedef pair<int, LL> pil;
typedef pair<LL, int> pli;
typedef pair<LL, LL> pll;
typedef vector<pil> vil;
typedef vector<pii> vii;
typedef vector<pli> vli;
typedef vector<pll> vll;

const int iinf = 1e9 + 7;
const LL linf = 1ll << 60;
const flt dinf = 1e60;

template <typename T> inline void scf(T &x) {
  bool f = 0;
  x = 0;
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-')
    c = getchar();
  if (c == '-') {
    f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  if (f)
    x = -x;
  return;
}

template <typename T1, typename T2> void scf(T1 &x, T2 &y) {
  scf(x);
  return scf(y);
}

template <typename T1, typename T2, typename T3> void scf(T1 &x, T2 &y, T3 &z) {
  scf(x);
  scf(y);
  return scf(z);
}

template <typename T1, typename T2, typename T3, typename T4>
void scf(T1 &x, T2 &y, T3 &z, T4 &w) {
  scf(x);
  scf(y);
  scf(z);
  return scf(w);
}

inline char mygetchar() {
  char c = getchar();
  while (c == ' ' || c == '\\n')
    c = getchar();
  return c;
}

template <typename T> void chkmax(T &x, const T &y) {
  if (y > x)
    x = y;
  return;
}

template <typename T> void chkmin(T &x, const T &y) {
  if (y < x)
    x = y;
  return;
}

#ifdef ONLINE_JUDGE
#define debug(x, c) ;
#else
#define DEBUG
#define debug(x, c) cerr << #x << "=" << x << c;
#endif

//---------------------------head----------------------------

const int N = 1e3 + 100;
const int mod = 1e9 + 7;

int n, diameter_length, min_D;
int dp[N][N], tag[N][N], current_time;
vi g[N];
vi diameter_path;

namespace TREE {
int par[N], dep[N];

void dfs(int u = 1, int fa = 0) {
  par[u] = fa;
  dep[u] = dep[fa] + 1;
  for (int v : g[u])
    if (v != fa)
      dfs(v, u);
  return;
}

void get_diameter() {
  dfs();
  int mx = -1, S, T;
  forn(i, 1, n) if (dep[i] > mx) mx = dep[i], S = i;
  dfs(S);
  mx = -1;
  forn(i, 1, n) if (dep[i] > mx) mx = dep[i], T = i;

  diameter_length = dep[T] - 1;
  min_D = dep[T] >> 1;

  int u = T;
  while (u != S)
    diameter_path.pb(u), u = par[u];
  diameter_path.pb(S);
  return;
}
} // namespace TREE

void MEI() {
  scf(n);
  rep(i, n - 1) {
    int u, v;
    scf(u, v);
    g[u].pb(v);
    g[v].pb(u);
  }

  TREE::get_diameter();
  return;
}

namespace Bamboo {
void solve() {
  for (;;)
    ;
  dp[0][0] = 1;
  forn(i, 1, n - 1) {
    dp[i][0] = dp[i][i] = 1;
    forn(j, 1, i - 1) dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
  }
  printf("%d\\n", dp[n - 1][min_D] * 2 % mod);
  return;
}
} // namespace Bamboo

void DP(int u, int par, int max_down, int max_up) {
  if (tag[u][max_down] == current_time)
    return;

  tag[u][max_down] = current_time;
  int &t = dp[u][max_down];
  t = 1;

  for (int v : g[u])
    if (v != par) {
      int foo = 0;
      if (max_down)
        DP(v, u, max_down - 1, max_up), foo += dp[v][max_down - 1];
      if (max_up)
        DP(v, u, max_down, max_up - 1), foo += dp[v][max_down];
      t = 1ll * t * foo % mod;
    }
  return;
}

namespace Odd {
int ans = 0;
int root1, root2;

void case1() {
  rep(down2, min_D) {
    int up1 = min_D - 1 - down2;
    int up2 = up1, down1 = down2;

    current_time++;
    DP(root2, root1, down2, up2);
    int foo = dp[root2][down2];

    current_time++;
    DP(root1, root2, down1, up1);
    foo = 1ll * foo * dp[root1][down1] % mod;
    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void case2() {
  forn(down2, 1, min_D - 1) {
    int up2 = min_D - 1 - down2;
    int up1 = min_D - down2;
    int down1 = min_D - 1 - up1;

    current_time++;
    DP(root2, root1, down2, up2);
    int foo = dp[root2][down2];

    current_time++;
    DP(root1, root2, down1, up1);
    foo = 1ll * foo * dp[root1][down1] % mod;
    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void case3() {
  rep(down2, min_D) {
    int up1 = min_D - down2;
    int up2 = up1 - 1;
    int down1 = min_D - up1;

    current_time++;
    DP(root2, root1, down2, up2);
    int foo = dp[root2][down2];

    current_time++;
    DP(root1, root2, down1, up1);
    LL bar = dp[root1][down1];
    if (down1 > 0) {
      current_time++;
      DP(root1, root2, down1 - 1, up1);
      bar += mod - dp[root1][down1 - 1];
    }
    if (up1 > 0) {
      current_time++;
      DP(root1, root2, down1, up1 - 1);
      bar += mod - dp[root1][down1];
    }

    foo = 1ll * foo * bar % mod;
    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void case4() {
  forn(down2, 1, min_D) {
    int up1 = min_D - down2;
    int up2 = up1;
    int down1 = min_D - 1 - up1;

    current_time++;
    DP(root2, root1, down2, up2);
    LL foo = dp[root2][down2];
    if (up2 > 0) {
      current_time++;
      DP(root2, root1, down2, up2 - 1);
      foo += mod - dp[root2][down2];
    }
    if (down2 > 0) {
      current_time++;
      DP(root2, root1, down2 - 1, up2);
      foo += mod - dp[root2][down2 - 1];
    }

    current_time++;
    DP(root1, root2, down1, up1);
    foo = foo * 1ll * dp[root1][down1] % mod;

    ans += foo;
    if (ans >= mod)
      ans -= mod;
  }
  debug(ans, '\\n') return;
}

void solve() {
  root1 = diameter_path[min_D - 1];
  root2 = diameter_path[min_D];
  case1();
  case2();
  case3();
  case4();
  ans += ans;
  if (ans >= mod)
    ans -= mod;
  printf("%d\\n", ans);
  return;
}
} // namespace Odd

namespace Even {
void solve() {
  int root = diameter_path[min_D];
  int ans = 0;
  forn(max_down, 0, min_D) {
    current_time++;
    DP(root, 0, max_down, min_D - max_down);
    ans += dp[root][max_down];
    if (ans >= mod)
      ans -= mod;
  }
  printf("%d\\n", ans);
  return;
}
} // namespace Even

void ZI() {
  if (diameter_length == n - 1)
    Bamboo::solve();
  else if (diameter_length & 1)
    Odd::solve();
  else
    Even::solve();
  return;
}

/*
   Main
   code
   is
   over
   .
   If
   you
   are
   in
   a
   hurry
   trying
   to
   hack
   me
   you
   don't
   need
   to
   read
   the
   part
   left
   .
   Trust
   me
   .
   It
   is
   useless
   .
   My
   code
   always
gets
a
failed
system
test
,
so
it
will
be
pretty
easy
for
you
to
hack
me
.
Just
find
a
test
case
and
hack
.
Wish
you
all
happy
hack
.
 _____
/     \\
| . . |
|     |
|  |  |
| --- |
| \\_/ |
\\_____/

*/

#ifdef DEBUG

struct I {
  int x;
  I() {}
  I(int y) : x(y) {}
  bool operator<(const I &a) const { return x < a.x; }
};

pair<I, LL> time_limit_exceeded;
const bool FLAG = 1;
static vector<I> wrong_answer;
I *RP = new I;

I FUCK = min(I{*RP}, I{0});
static int memory_limit_exceeded[10];
vi O() {
  cout << FUCK.x << endl;
  vi ert;
  int x = 0;
  x = (int)hypot(3.0, 4.0);
  ert.pb(x);
  if (x & 1)
    exit(0);
  auto t = lower_bound(ALL(ert), 5);
  static list<int> runtime_error_;
  return ert;
}
#endif // DEBUG

#define MEI int
#define ZI main
MEI ZI() {
#undef MEI
#undef ZI

  MEI();
  ZI();

#define BA return
#define MEI 0
#define ZI ;
  BA MEI ZI
#undef BA
#undef MEI
#undef ZI
}