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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <vector>
using namespace std;

namespace my {
//-----------------------------------------------------------------------------
inline char cn() {
  static char buf[1000010], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
#define cn getchar
template <class TY> void read(TY &x) {
  x = 0;
  int f1 = 1;
  char ch = cn();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f1 = -1;
    ch = cn();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + (ch - '0'), ch = cn();
  x *= f1;
}
char Output[1000100], Zk[100];
int op_top = 0, Zk_top;
void fcheck(int Type = 0) {
  if (Type || op_top >= 1000000)
    fwrite(Output, 1, op_top, stdout), op_top = 0;
}
template <class TY> inline void write(TY x) {
  if (x == 0) {
    Output[op_top++] = '0';
    fcheck();
    return;
  }
  if (x < 0)
    Output[op_top++] = '-', x = -x;
  Zk_top = 0;
  while (x)
    Zk[++Zk_top] = x % 10 + '0', x /= 10;
  while (Zk_top)
    Output[op_top++] = Zk[Zk_top--];
  fcheck();
}
#define K_G Output[op_top++] = ' '
#define H_C Output[op_top++] = '\\n'
//--------------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------------
#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define db double
#define pb push_back
#define INV(x) ksm(x, mod - 2)
#define inf 999999999
#define mod 998244353

void add(int &x, int y) { x = (x + y >= mod ? x + y - mod : x + y); }
void dec(int &x, int y) { x = (x - y < 0 ? x - y + mod : x - y); }
template <class TY> TY add(TY x) { return x >= mod ? x - mod : x; }
template <class TY> TY dec(TY x) { return x < 0 ? x + mod : x; }
template <class TY> void chkmin(TY &x, TY y) {
  if (y < x)
    x = y;
}
template <class TY> void chkmax(TY &x, TY y) {
  if (y > x)
    x = y;
}
//
int ksm(int x, int y) {
  int re = 1;
  for (; (y & 1 ? re = 1ll * re * x % mod : 0), y;
       y >>= 1, x = 1ll * x * x % mod)
    ;
  return re;
}
template <class TY> void discretization(TY *arr, int St, int Ed) {
  vector<TY> Arr;
  Arr.clear();
  for (int i = St; i <= Ed; i++)
    Arr.push_back(arr[i]);
  sort(Arr.begin(), Arr.end());
  for (int i = St; i <= Ed; i++)
    arr[i] = lower_bound(Arr.begin(), Arr.end(), arr[i]) - Arr.begin() + 1;
}
//-----------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------
#define maxn 200010
#define mod 998244353
int n, a[maxn], b[maxn], f[maxn], tmp[maxn]; // f[i]:at least i pairs are same
int fac[maxn], inv[maxn], inv_fac[maxn];
void FacInit() {
  fac[0] = inv_fac[0] = inv[1] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = 1ll * fac[i - 1] * i % mod;
  for (int i = 2; i <= n; i++)
    inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
  for (int i = 1; i <= n; i++)
    inv_fac[i] = 1ll * inv_fac[i - 1] * inv[i] % mod;
}
int C(int x, int y) {
  if (x < y || y < 0)
    return 0;
  return 1ll * fac[x] * inv_fac[y] % mod * inv_fac[x - y] % mod;
}
const int inv2 = (mod + 1) / 2;
int d[maxn];

void main() {
  read(n);
  n <<= 1;
  FacInit();
  for (int i = 1; i <= n; i++)
    read(a[i]), b[a[i]]++;
  f[0] = 1;
  int ma = 0;
  d[0] = 1;
  for (int i = 2, in = inv2; i <= n; i += 2, in = 1ll * in * inv2 % mod)
    d[i] = 1ll * fac[i] * in % mod * inv_fac[i / 2] % mod;
  for (int i = 1; i <= 100000; i++)
    if (b[i] > 1) {
      for (int j = 1; j <= b[i] / 2; j++) {
        int p = 1ll * C(b[i], j * 2) * d[2 * j] % mod;
        for (int k = 0; k <= ma; k++) {
          add(tmp[k + j], 1ll * f[k] * p % mod);
        }
      }
      ma += b[i] / 2;
      for (int j = 0; j <= ma; j++)
        add(f[j], tmp[j]), tmp[j] = 0;
    }
  int ans = 0;
  for (int i = 0; i <= ma; i++) {
    if (i & 1)
      dec(ans, 1ll * f[i] * d[n - 2 * i] % mod);
    else
      add(ans, 1ll * f[i] * d[n - 2 * i] % mod);
  }
  write(ans);
  fcheck(1);
  return;
}
} // namespace my

int main() {
  my::main();
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <vector>
using namespace std;

namespace my {
//-----------------------------------------------------------------------------
inline char cn() {
  static char buf[1000010], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
#define cn getchar
template <class TY> void read(TY &x) {
  x = 0;
  int f1 = 1;
  char ch = cn();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f1 = -1;
    ch = cn();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + (ch - '0'), ch = cn();
  x *= f1;
}
char Output[1000100], Zk[100];
int op_top = 0, Zk_top;
void fcheck(int Type = 0) {
  if (Type || op_top >= 1000000)
    fwrite(Output, 1, op_top, stdout), op_top = 0;
}
template <class TY> inline void write(TY x) {
  if (x == 0) {
    Output[op_top++] = '0';
    fcheck();
    return;
  }
  if (x < 0)
    Output[op_top++] = '-', x = -x;
  Zk_top = 0;
  while (x)
    Zk[++Zk_top] = x % 10 + '0', x /= 10;
  while (Zk_top)
    Output[op_top++] = Zk[Zk_top--];
  fcheck();
}
#define K_G Output[op_top++] = ' '
#define H_C Output[op_top++] = '\\n'
//--------------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------------
#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define db double
#define pb push_back
#define INV(x) ksm(x, mod - 2)
#define inf 999999999
#define mod 998244353

template <class TY> void add(TY &x, TY y) {
  x = (x + y >= mod ? x + y - mod : x + y);
}
template <class TY> void dec(TY &x, TY y) {
  x = (x - y < 0 ? x - y + mod : x - y);
}
template <class TY> TY add(TY x) { return x >= mod ? x - mod : x; }
template <class TY> TY dec(TY x) { return x < 0 ? x + mod : x; }
template <class TY> void chkmin(TY &x, TY y) {
  if (y < x)
    x = y;
}
template <class TY> void chkmax(TY &x, TY y) {
  if (y > x)
    x = y;
}
//
int ksm(int x, int y) {
  int re = 1;
  for (; (y & 1 ? re = 1ll * re * x % mod : 0), y;
       y >>= 1, x = 1ll * x * x % mod)
    ;
  return re;
}
template <class TY> void discretization(TY *arr, int St, int Ed) {
  vector<TY> Arr;
  Arr.clear();
  for (int i = St; i <= Ed; i++)
    Arr.push_back(arr[i]);
  sort(Arr.begin(), Arr.end());
  for (int i = St; i <= Ed; i++)
    arr[i] = lower_bound(Arr.begin(), Arr.end(), arr[i]) - Arr.begin() + 1;
}
//-----------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------
#define maxn 200010
#define mod 998244353
int n, a[maxn], b[maxn], f[maxn], tmp[maxn]; // f[i]:at least i pairs are same
int fac[maxn], inv[maxn], inv_fac[maxn];
void FacInit() {
  fac[0] = inv_fac[0] = inv[1] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = 1ll * fac[i - 1] * i % mod;
  for (int i = 2; i <= n; i++)
    inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
  for (int i = 1; i <= n; i++)
    inv_fac[i] = 1ll * inv_fac[i - 1] * inv[i] % mod;
}
int C(int x, int y) {
  if (x < y || y < 0)
    return 0;
  return 1ll * fac[x] * inv_fac[y] % mod * inv_fac[x - y] % mod;
}
const int inv2 = (mod + 1) / 2;
int d[maxn];

void main() {
  read(n);
  n <<= 1;
  FacInit();
  for (int i = 1; i <= n; i++)
    read(a[i]), b[a[i]]++;
  f[0] = 1;
  int ma = 0;
  d[0] = 1;
  for (int i = 2, in = inv2; i <= n; i += 2, in = 1ll * in * inv2 % mod)
    d[i] = 1ll * fac[i] * in % mod * inv_fac[i / 2] % mod;
  for (int i = 1; i <= 100000; i++)
    if (b[i] > 1) {
      for (int j = 1; j <= b[i] / 2; j++) {
        int p = 1ll * C(b[i], j * 2) * d[2 * j] % mod;
        for (int k = 0; k <= ma; k++) {
          tmp[k + j] = (tmp[k + j] + 1ll * f[k] * p % mod) % mod;
        }
      }
      ma += b[i] / 2;
      for (int j = 0; j <= ma; j++)
        add(f[j], tmp[j]), tmp[j] = 0;
    }
  int ans = 0;
  for (int i = 0; i <= ma; i++) {
    //			printf("%d ",f[i]);
    if (i & 1)
      ans = (ans - 1ll * f[i] * d[n - 2 * i] % mod + mod) % mod;
    else
      ans = (ans + 1ll * f[i] * d[n - 2 * i] % mod) % mod;
    //			printf("%d\\n",ans);
  }
  //		printf("\\n");
  printf("%d", ans);
  fcheck(1);
  return;
}
} // namespace my

int main() {
  my::main();
  return 0;
}