QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#381098#4114. 序列统计Elegia❄️100 ✓87ms4352kbC++1418.7kb2024-04-07 16:15:502024-04-07 16:15:50

Judging History

This is the latest submission verdict.

  • [2024-04-07 16:15:50]
  • Judged
  • Verdict: 100
  • Time: 87ms
  • Memory: 4352kb
  • [2024-04-07 16:15:50]
  • Submitted

answer

#include <cstdio>
#include <cstring>

#include <algorithm>
#include <chrono>
#include <random>
#include <functional>
#include <vector>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;

const int P = 1004535809, R = 3;

int mpow(int x, int k, int p = P) {
  int ret = 1;
  while (k) {
    if (k & 1)
      ret = ret * (ll)x % p;
    x = x * (ll)x % p;
    k >>= 1;
  }
  return ret;
}

struct NumberTheory {

  typedef pair<int, int> _P2_Field;

  mt19937 rng;

  NumberTheory() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}

  void _exGcd(int a, int b, int& x, int& y) {
    if (!b) {
      x = 1;
      y = 0;
      return;
    }
    _exGcd(b, a % b, y, x);
    y -= a / b * x;
  }

  int inv(int a, int p = P) {
    int x, y;
    _exGcd(a, p, x, y);
    if (x < 0)
      x += p;
    return x;
  }

  template <class Integer>
  bool quadRes(Integer a, Integer b) {
    if (a <= 1)
      return true;
    while (a % 4 == 0)
      a /= 4;
    if (a % 2 == 0)
      return (b % 8 == 1 || b % 8 == 7) == quadRes(a / 2, b);
    return ((a - 1) % 4 == 0 || (b - 1) % 4 == 0) == quadRes(b % a, a);
  }

  // assume p in prime, x in quadratic residue
  int sqrt(int x, int p = P) {
    if (p == 2 || x <= 1)
      return x;
    int w, v, k = (p + 1) / 2;
    do {
      w = rng() % p;
    } while (quadRes(v = int((w * (ll)w - x + p) % p), p));
    _P2_Field res(1, 0), a(w, 1);
    while (k) {
      if (k & 1)
        res = _P2_Field((res.first * (ll)a.first + res.second * (ll)a.second % p * v) % p, (res.first * (ll)a.second + res.second * (ll)a.first) % p);
      if (k >>= 1)
        a = _P2_Field((a.first * (ll)a.first + a.second * (ll)a.second % p * v) % p, (a.first * (ll)a.second << 1) % p);
    }
    return min(res.first, p - res.first);
  }

} nt;

struct Simple {
  int n;
  vector<int> fac, ifac, inv;

  void build(int n) {
    this->n = n;
    fac.resize(n + 1);
    ifac.resize(n + 1);
    inv.resize(n + 1);
    fac[0] = 1;
    for (int x = 1; x <= n; ++x)
      fac[x] = fac[x - 1] * (ll)x % P;
    inv[1] = 1;
    for (int x = 2; x <= n; ++x)
      inv[x] = -(P / x) * (ll)inv[P % x] % P + P;
    ifac[0] = 1;
    for (int x = 1; x <= n; ++x)
      ifac[x] = ifac[x - 1] * (ll)inv[x] % P;
  }

  Simple() {
    build(1);
  }

  void check(int k) {
    int nn = n;
    if (k > nn) {
      while (k > nn)
        nn <<= 1;
      build(nn);
    }
  }

  int gfac(int k) {
    check(k);
    return fac[k];
  }

  int gifac(int k) {
    check(k);
    return ifac[k];
  }

  int ginv(int k) {
    check(k);
    return inv[k];
  }

  int binom(int n, int m) {
    if (m < 0 || m > n)
      return 0;
    return gfac(n) * (ll)gifac(m) % P * gifac(n - m) % P;
  }
} simp;

const int L2 = 11;

struct NTT {
  int brev[1 << L2];

  NTT() {
    for (int i = 1; i < (1 << L2); ++i)
      brev[i] = brev[i >> 1] >> 1 | ((i & 1) << (L2 - 1));
  }

  void fft(int* a, int lgn, int d = 1) {
    int n = 1 << lgn;
    for (int i = 0; i < n; ++i) {
      int rev = (brev[i >> L2] | (brev[i & ((1 << L2) - 1)] << L2)) >> ((L2 << 1) - lgn);
      if (i < rev)
        swap(a[i], a[rev]);
    }
    int rt = d == 1 ? R : nt.inv(R);
    for (int i = 0; i < lgn; ++i) {
      int t = 1 << i;
      int omega = mpow(rt, (P - 1) >> (i + 1));
      for (int j = 0; j < n; j += t << 1) {
        int w = 1;
        for (int k = 0; k < t; ++k) {
          int a0 = a[j + k], a1 = a[j + k + t];
          a[j + k] = (a0 + w * (ll)a1) % P;
          a[j + k + t] = (a0 + (P - w) * (ll)a1) % P;
          w = w * (ll)omega % P;
        }
      }
    }
    if (d == -1) {
      int in = nt.inv(n);
      for (int i = 0; i < n; ++i)
        a[i] = a[i] * (ll)in % P;
    }
  }
} ntt;

struct Poly {
  vector<int> a;

  Poly(int v = 0) : a(1) {
    if ((v %= P) < 0)
      v += P;
    a[0] = v;
  }

  Poly(const vector<int>& a) : a(a) {}

  Poly(initializer_list<int> init) : a(init) {}

  // Helps
  int operator[](int k) const { return k < a.size() ? a[k] : 0; }

  int& operator[](int k) {
    if (k >= a.size())
      a.resize(k + 1);
    return a[k];
  }

  int deg() const { return a.size() - 1; }

  void redeg(int d) { a.resize(d + 1); }

  Poly monic() const;
  Poly sunic() const;

  Poly slice(int d) const {
    if (d < a.size())
      return vector<int>(a.begin(), a.begin() + d + 1);
    vector<int> res(a);
    res.resize(d + 1);
    return res;
  }

  int* base() { return a.begin().base(); }
  const int* base() const { return a.begin().base(); }

  Poly println(FILE* fp) const {
    fprintf(fp, "%d", a[0]);
    for (int i = 1; i < a.size(); ++i)
      fprintf(fp, " %d", a[i]);
    fputc('\n', fp);
    return *this;
  }

  // Calculations
  Poly operator+(const Poly& rhs) const {
    vector<int> res(max(a.size(), rhs.a.size()));
    for (int i = 0; i < res.size(); ++i)
      if ((res[i] = operator[](i) + rhs[i]) >= P)
        res[i] -= P;
    return res;
  }

  Poly operator-() const {
    Poly ret(a);
    for (int i = 0; i < a.size(); ++i)
      if (ret[i])
        ret[i] = P - ret[i];
    return ret;
  }

  Poly operator-(const Poly& rhs) const { return operator+(-rhs); }

  Poly operator*(const Poly& rhs) const;

  Poly operator/(const Poly& rhs) const;

  Poly operator%(const Poly& rhs) const;

  Poly der() const; // default: remove trailing
  Poly integ() const;

  Poly inv() const;
  Poly sqrt() const;
  Poly ln() const;
  Poly exp() const;
  pair<Poly, Poly> sqrti() const;

  Poly quo(const Poly& rhs) const;
  pair<Poly, Poly> iquo(const Poly& rhs) const;

  Poly taylor(int k) const;
  Poly pow(int k) const;
  Poly exp(int k) const;
};

Poly zeroes(int deg) { return vector<int>(deg + 1); }

struct Newton {
  void inv(const Poly& f, const Poly& nttf, Poly& g, const Poly& nttg, int t) {
    int n = 1 << t;
    Poly prod = nttf;
    for (int i = 0; i < (n << 1); ++i)
      prod[i] = prod[i] * (ll)nttg[i] % P;
    ntt.fft(prod.base(), t + 1, -1);
    for (int i = 0; i < n; ++i)
      prod[i] = 0;
    ntt.fft(prod.base(), t + 1, 1);
    for (int i = 0; i < (n << 1); ++i)
      prod[i] = prod[i] * (ll)nttg[i] % P;
    ntt.fft(prod.base(), t + 1, -1);
    for (int i = 0; i < n; ++i)
      prod[i] = 0;
    g = g - prod;
  }

  void inv(const Poly& f, const Poly& nttf, Poly& g, int t) {
    Poly nttg = g;
    nttg.redeg((2 << t) - 1);
    ntt.fft(nttg.base(), t + 1, 1);
    inv(f, nttf, g, nttg, t);
  }

  void inv(const Poly& f, Poly& g, int t) {
    Poly nttg = g;
    nttg.redeg((2 << t) - 1);
    ntt.fft(nttg.base(), t + 1, 1);
    Poly nttf = f;
    nttf.redeg((2 << t) - 1);
    ntt.fft(nttf.base(), t + 1, 1);
    inv(f, nttf, g, nttg, t);
  }

  void sqrt(const Poly& f, Poly& g, Poly& nttg, Poly& h, int t) {
    for (int i = 0; i < (1 << t); ++i)
      nttg[i] = mpow(nttg[i], 2);
    ntt.fft(nttg.base(), t, -1);
    nttg = nttg - f;
    for (int i = 0; i < (1 << t); ++i)
      if ((nttg[i + (1 << t)] += nttg[i]) >= P)
        nttg[i + (1 << t)] -= P;
    memset(nttg.base(), 0, sizeof(int) << t);
    ntt.fft(nttg.base(), t + 1, 1);
    Poly tmp = h;
    tmp.redeg((2 << t) - 1);
    ntt.fft(tmp.base(), t + 1, 1);
    for (int i = 0; i < (2 << t); ++i)
      tmp[i] = tmp[i] * (ll)nttg[i] % P;
    ntt.fft(tmp.base(), t + 1, -1);
    memset(tmp.base(), 0, sizeof(int) << t);
    g = g - tmp * nt.inv(2);
  }

  void exp(const Poly& f, Poly& g, Poly& nttg, Poly& h, int t) {
    Poly ntth(h);
    ntt.fft(ntth.base(), t, 1);
    Poly dg = g.der().slice((1 << t) - 1);
    ntt.fft(dg.base(), t, 1);
    Poly tmp = zeroes((1 << t) - 1);
    for (int i = 0; i < (1 << t); ++i) {
      tmp[i] = nttg[i << 1] * (ll)ntth[i] % P;
      dg[i] = dg[i] * (ll)ntth[i] % P;
    }
    ntt.fft(tmp.base(), t, -1);
    ntt.fft(dg.base(), t, -1);
    if (--tmp[0] < 0)
      tmp[0] = P - 1;
    dg.redeg((2 << t) - 1);
    Poly df0 = f.der().slice((1 << t) - 1);
    df0[(1 << t) - 1] = 0;
    for (int i = 0; i < (1 << t); ++i) {
      if ((dg[i | 1 << t] = dg[i] - df0[i]) < 0)
        dg[i | 1 << t] += P;
    }
    memcpy(dg.base(), df0.base(), sizeof(int) * ((1 << t) - 1));
    tmp.redeg((2 << t) - 1);
    ntt.fft(tmp.base(), t + 1, 1);
    df0.redeg((2 << t) - 1);
    ntt.fft(df0.base(), t + 1, 1);
    for (int i = 0; i < (2 << t); ++i)
      df0[i] = df0[i] * (ll)tmp[i] % P;
    ntt.fft(df0.base(), t + 1, -1);
    memcpy(df0.base() + (1 << t), df0.base(), sizeof(int) << t);
    memset(df0.base(), 0, sizeof(int) << t);
    dg = (dg - df0).integ().slice((2 << t) - 1) - f;
    ntt.fft(dg.base(), t + 1, 1);
    for (int i = 0; i < (2 << t); ++i)
      tmp[i] = dg[i] * (ll)nttg[i] % P;
    ntt.fft(tmp.base(), t + 1, -1);
    g.redeg((2 << t) - 1);
    for (int i = 1 << t; i < (2 << t); ++i)
      if (tmp[i])
        g[i] = P - tmp[i];
  }
} nit;

struct EvaluationHelper {

  int _t, _lim;
  vector<int> _tmp, _res, _tmpy;
  vector<Poly> _h, _r;

  EvaluationHelper() {}

  void _solve(int l, int r) {
    if (l == r) {
      _h[_t] = Poly{(P - _tmp[l]) % P, 1};
      ++_t;
      return;
    }
    int p = _t++;
    int ls = _t, mid = (l + r) >> 1;
    _solve(l, mid);
    int rs = _t;
    _solve(mid + 1, r);
    if ((r - l + 1) <= _lim)
      _h[p] = _h[ls] * _h[rs];
  }

  void _solve2(int l, int r) {
    if ((r - l + 1) <= _lim)
      _r[_t] = _r[_t] % _h[_t];
    if (l == r) {
      _res[l] = _r[_t][0];
      ++_t;
      return;
    }
    int p = _t++, mid = (l + r) >> 1;
    _r[_t] = _r[p] % _h[_t];
    _solve2(l, mid);
    _r[_t] = _r[p] % _h[_t];
    _solve2(mid + 1, r);
  }

  void _divideConquer(int l, int r) {
    if (l == r) {
      _r[_t] = nt.inv(_res[l]) * (ll)_tmpy[l] % P;
      ++_t;
      return;
    }
    int p = _t++, mid = (l + r) >> 1;
    int ls = _t;
    _divideConquer(l, mid);
    int rs = _t;
    _divideConquer(mid + 1, r);
    _r[p] = _r[ls] * _h[rs] + _r[rs] * _h[ls];
  }

  vector<int> evaluate(const Poly& p, const vector<int>& x) {
    if (x.empty())
      return vector<int>();
    int n = x.size();
    _lim = n;
    _tmp = x;
    _h.resize(n * 2 - 1);
    _r.resize(n * 2 - 1);
    _t = 0;
    _solve(0, n - 1);
    _res.resize(n);
    _t = 0;
    _r[0] = p;
    _solve2(0, n - 1);
    _tmp.clear();
    _h.clear();
    _r.clear();
    return _res;
  }

  Poly interpolate(const vector<pair<int, int> >& points) {
    int n = points.size();
    _tmp.resize(n);
    for (int i = 0; i < n; ++i)
      _tmp[i] = points[i].first;
    _lim = n;
    _h.resize(n * 2 - 1);
    _r.resize(n * 2 - 1);
    _t = 0;
    _solve(0, n - 1);
    _res.resize(n);
    _t = 0;
    _r[0] = _h[0].der();
    _solve2(0, n - 1);
    _tmp.clear();
    _tmpy.resize(n);
    for (int i = 0; i < n; ++i)
      _tmpy[i] = points[i].second;
    _t = 0;
    _divideConquer(0, n - 1);
    return _r[0];
  }
} eh;

Poly operator "" _z(unsigned long long a) { return {0, (int)a}; }

Poly operator+(int v, const Poly& rhs) { return Poly(v) + rhs; }

Poly Poly::operator*(const Poly& rhs) const {
  int n = deg(), m = rhs.deg();
  if (n <= 10 || m <= 10) {
    Poly ret = zeroes(n + m);
    for (int i = 0; i <= n; ++i)
      for (int j = 0; j <= m; ++j)
        ret[i + j] = (ret[i + j] + a[i] * (ll)rhs[j]) % P;
    return ret;
  }
  n += m;
  int l = 0;
  while ((1 << l) <= n)
    ++l;
  vector<int> res(1 << l), tmp(1 << l);
  memcpy(res.begin().base(), base(), a.size() * sizeof(int));
  ntt.fft(res.begin().base(), l, 1);
  memcpy(tmp.begin().base(), rhs.base(), rhs.a.size() * sizeof(int));
  ntt.fft(tmp.begin().base(), l, 1);
  for (int i = 0; i < (1 << l); ++i)
    res[i] = res[i] * (ll)tmp[i] % P;
  ntt.fft(res.begin().base(), l, -1);
  res.resize(n + 1);
  return res;
}

Poly Poly::inv() const {
  Poly g = nt.inv(a[0]);
  for (int t = 0; (1 << t) <= deg(); ++t)
    nit.inv(slice((2 << t) - 1), g, t);
  g.redeg(deg());
  return g;
}

Poly Poly::taylor(int k) const {
  int n = deg();
  Poly t = zeroes(n);
  simp.check(n);
  for (int i = 0; i <= n; ++i)
    t[n - i] = a[i] * (ll)simp.fac[i] % P;
  int pw = 1;
  Poly help = vector<int>(simp.ifac.begin(), simp.ifac.begin() + n + 1);
  for (int i = 0; i <= n; ++i) {
    help[i] = help[i] * (ll)pw % P;
    pw = pw * (ll)k % P;
  }
  t = t * help;
  for (int i = 0; i <= n; ++i)
    help[i] = t[n - i] * (ll)simp.ifac[i] % P;
  return help;
}

Poly Poly::pow(int k) const {
  if (k == 0)
    return 1;
  if (k == 1)
    return *this;
  int n = deg() * k;
  int lgn = 0;
  while ((1 << lgn) <= n)
    ++lgn;
  vector<int> val = a;
  val.resize(1 << lgn);
  ntt.fft(val.begin().base(), lgn, 1);
  for (int i = 0; i < (1 << lgn); ++i)
    val[i] = mpow(val[i], k);
  ntt.fft(val.begin().base(), lgn, -1);
  return val;
}

Poly Poly::der() const {
  if (deg() == 0)
    return 0;
  vector<int> res(deg());
  for (int i = 0; i < deg(); ++i)
    res[i] = a[i + 1] * (ll)(i + 1) % P;
  return res;
}

Poly Poly::integ() const {
  vector<int> res(deg() + 2);
  simp.check(deg() + 1);
  for (int i = 0; i <= deg(); ++i)
    res[i + 1] = a[i] * (ll)simp.inv[i + 1] % P;
  return res;
}

Poly Poly::quo(const Poly &rhs) const {
  if (rhs.deg() == 0)
    return a[0] * (ll) nt.inv(rhs[0]) % P;
  Poly g = nt.inv(rhs[0]);
  int t = 0, n;
  for (n = 1; (n << 1) <= rhs.deg(); ++t, n <<= 1)
    nit.inv(rhs.slice((n << 1) - 1), g, t);
  Poly nttg = g;
  nttg.redeg((n << 1) - 1);
  ntt.fft(nttg.base(), t + 1, 1);
  Poly eps1 = rhs.slice((n << 1) - 1);
  ntt.fft(eps1.base(), t + 1, 1);
  for (int i = 0; i < (n << 1); ++i)
    eps1[i] = eps1[i] * (ll) nttg[i] % P;
  ntt.fft(eps1.base(), t + 1, -1);
  memcpy(eps1.base(), eps1.base() + n, sizeof(int) << t);
  memset(eps1.base() + n, 0, sizeof(int) << t);
  ntt.fft(eps1.base(), t + 1, 1);
  Poly h0 = slice(n - 1);
  h0.redeg((n << 1) - 1);
  ntt.fft(h0.base(), t + 1);
  Poly h0g0 = zeroes((n << 1) - 1);
  for (int i = 0; i < (n << 1); ++i)
    h0g0[i] = h0[i] * (ll)nttg[i] % P;
  ntt.fft(h0g0.base(), t + 1, -1);
  Poly h0eps1 = zeroes((n << 1) - 1);
  for (int i = 0; i < (n << 1); ++i)
    h0eps1[i] = h0[i] * (ll)eps1[i] % P;
  ntt.fft(h0eps1.base(), t + 1, -1);
  for (int i = 0; i < n; ++i) {
    h0eps1[i] = operator[](i + n) - h0eps1[i];
    if (h0eps1[i] < 0)
      h0eps1[i] += P;
  }
  memset(h0eps1.base() + n, 0, sizeof(int) << t);
  ntt.fft(h0eps1.base(), t + 1);
  for (int i = 0; i < (n << 1); ++i)
    h0eps1[i] = h0eps1[i] * (ll)nttg[i] % P;
  ntt.fft(h0eps1.base(), t + 1, -1);
  memcpy(h0eps1.base() + n, h0eps1.base(), sizeof(int) << t);
  memset(h0eps1.base(), 0, sizeof(int) << t);
  return (h0g0 + h0eps1).slice(rhs.deg());
}

Poly Poly::ln() const {
  if (deg() == 0)
    return 0;
  return der().quo(slice(deg() - 1)).integ();
}

pair<Poly, Poly> Poly::sqrti() const {
  Poly g = nt.sqrt(a[0]), h = nt.inv(g[0]), nttg = g;
  for (int t = 0; (1 << t) <= deg(); ++t) {
    nit.sqrt(slice((2 << t) - 1), g, nttg, h, t);
    nttg = g;
    ntt.fft(nttg.base(), t + 1, 1);
    nit.inv(g, nttg, h, t);
  }
  return make_pair(g.slice(deg()), h.slice(deg()));
}

Poly Poly::sqrt() const {
  Poly g = nt.sqrt(a[0]), h = nt.inv(g[0]), nttg = g;
  for (int t = 0; (1 << t) <= deg(); ++t) {
    nit.sqrt(slice((2 << t) - 1), g, nttg, h, t);
    if ((2 << t) <= deg()) {
      nttg = g;
      ntt.fft(nttg.base(), t + 1, 1);
      nit.inv(g, nttg, h, t);
    }
  }
  return g.slice(deg());
}

Poly Poly::exp() const {
  Poly g = 1, h = 1, nttg = {1, 1};
  for (int t = 0; (1 << t) <= deg(); ++t) {
    nit.exp(slice((2 << t) - 1), g, nttg, h, t);
    if ((2 << t) <= deg()) {
      nttg = g;
      nttg.redeg((4 << t) - 1);
      ntt.fft(nttg.base(), t + 2);
      Poly f2n = zeroes((2 << t) - 1);
      for (int i = 0; i < (2 << t); ++i)
        f2n[i] = nttg[i << 1];
      nit.inv(g, f2n, h, t);
    } else {
      nttg = g;
      ntt.fft(nttg.base(), t + 1, 1);
    }
  }
  return g.slice(deg());
}

Poly Poly::exp(int k) const {
  int lead, lz = 0;
  while (lz < deg() && !a[lz])
    ++lz;
  if (lz == deg() && !a[lz])
    return *this;
  lead = a[lz];
  if (lz * (ll)k > deg())
    return zeroes(deg());
  Poly part = Poly(vector<int>(a.begin() + lz, a.begin() + deg() - lz * (k - 1) + 1)) * nt.inv(lead);
  part = (part.ln() * k).exp() * mpow(lead, k);
  vector<int> ret(deg() + 1);
  memcpy(ret.begin().base() + lz * k, part.base(), sizeof(int) * (deg() - lz * k + 1));
  return ret;
}

Poly Poly::operator/(const Poly& rhs) const {
  int n = deg(), m = rhs.deg();
  if (n < m)
    return 0;
  Poly ta(vector<int>(a.rbegin(), a.rend())),
          tb(vector<int>(rhs.a.rbegin(), rhs.a.rend()));
  ta.redeg(n - m);
  tb.redeg(n - m);
  Poly q = ta.quo(tb);
  q.redeg(n - m);
  reverse(q.a.begin(), q.a.end());
  return q;
}

Poly Poly::operator%(const Poly &rhs) const {
  if (deg() < rhs.deg())
    return *this;
  Poly ret = (*this - (*this / rhs) * rhs);
  ret.redeg(rhs.deg() - 1);
  return ret;
}

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>

#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <limits>
#include <numeric>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int M = 8000;

int n, m, dc, r;
int d[M], dlog[M];

int main() {
#ifndef ONLINE_JUDGE
  freopen("test.in", "r", stdin);
  int nol_cl = clock();
#endif

  scanf("%d%d", &n, &m);
  for (int x = 1; x < m - 1; ++x)
    if ((m - 1) % x == 0)
      d[++dc] = x;
  for (r = 2; ; ++r) {
    bool flag = true;
    for (int i = 1; i <= dc; ++i)
      if (mpow(r, d[i], m) == 1) {
        flag = false;
        break;
      }
    if (flag)
      break;
  }
  int cur = 1, clog = 0;
  do {
    dlog[cur] = clog;
    ++clog;
    cur = cur * (ll)r % m;
  } while (cur != 1);
  int x, k;
  scanf("%d%d", &x, &k);
  x = dlog[x];
  Poly a = zeroes(m - 2);
  while (k--) {
    int v;
    scanf("%d", &v);
    if (v)
      a[dlog[v]] = 1;
  }
  Poly res = 1;
  while (n) {
    if (n & 1) {
      res = res * a;
      for (int j = m - 1; j <= res.deg(); ++j)
        if ((res[j - m + 1] += res[j]) >= P)
          res[j - m + 1] -= P;
      res.redeg(m - 2);
    }
    if (n >>= 1) {
      a = a * a;
      for (int j = m - 1; j <= a.deg(); ++j)
        if ((a[j - m + 1] += a[j]) >= P)
          a[j - m + 1] -= P;
      a.redeg(m - 2);
    }
  }
  printf("%d\n", res[x]);

#ifndef ONLINE_JUDGE
  LOG("Time: %dms\n", int ((clock()
          -nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
  return 0;
}

詳細信息


Pretests


Final Tests

Test #1:

score: 10
Accepted
time: 1ms
memory: 3968kb

input:

709 53 9 27
0 3 4 5 7 9 10 15 16 17 19 22 23 24 25 28 29 30 31 33 37 38 40 41 42 50 52

output:

170454910

result:

ok single line: '170454910'

Test #2:

score: 10
Accepted
time: 1ms
memory: 3840kb

input:

819644598 71 64 34
0 3 6 7 10 16 19 21 25 31 32 34 38 40 41 42 43 44 45 46 48 49 51 54 55 56 57 58 59 65 67 68 69 70

output:

599133595

result:

ok single line: '599133595'

Test #3:

score: 10
Accepted
time: 1ms
memory: 3840kb

input:

878507241 89 74 41
2 4 7 9 13 15 18 19 21 22 23 24 29 30 33 36 37 38 40 48 49 50 51 53 54 56 60 63 64 66 67 69 72 74 75 76 78 80 81 82 83

output:

249602758

result:

ok single line: '249602758'

Test #4:

score: 10
Accepted
time: 9ms
memory: 3968kb

input:

920165332 739 92 372
0 2 3 5 6 9 10 14 15 16 17 18 19 22 24 26 29 31 34 35 39 40 43 44 45 46 47 48 49 50 53 59 62 63 65 69 73 76 77 78 79 81 82 90 91 94 95 96 99 103 104 106 110 112 114 117 118 119 120 122 123 124 125 128 130 131 133 134 135 137 139 140 142 143 144 145 147 149 151 152 154 155 156 15...

output:

721859054

result:

ok single line: '721859054'

Test #5:

score: 10
Accepted
time: 8ms
memory: 4096kb

input:

992254127 733 613 359
0 2 4 5 7 9 10 12 14 16 17 19 20 23 24 25 28 30 31 32 36 39 42 43 47 48 49 51 52 53 55 58 60 61 63 64 65 66 68 69 70 72 78 79 80 81 82 85 86 89 90 92 94 96 100 102 103 106 109 113 114 120 121 123 124 127 129 130 133 134 137 140 143 144 145 147 150 151 155 157 158 161 162 164 16...

output:

317097647

result:

ok single line: '317097647'

Test #6:

score: 10
Accepted
time: 8ms
memory: 4096kb

input:

64343923 727 359 368
0 2 3 4 5 6 7 8 10 11 15 18 20 22 25 27 28 32 34 38 39 40 44 48 49 50 52 54 55 57 58 59 61 63 64 65 68 70 72 74 75 77 78 81 82 84 85 87 88 89 91 95 96 97 98 99 103 105 106 108 109 112 114 115 117 118 119 120 123 128 130 131 133 134 135 137 138 140 142 143 145 146 151 152 154 158...

output:

749710862

result:

ok single line: '749710862'

Test #7:

score: 10
Accepted
time: 68ms
memory: 4216kb

input:

152638504 5981 5475 3035
0 4 9 11 12 13 15 16 18 21 24 25 27 28 31 34 36 37 38 39 40 42 45 47 49 50 54 60 62 63 65 67 68 69 74 76 77 81 82 84 85 87 90 93 95 97 101 102 104 105 106 107 108 112 113 115 116 119 120 122 123 124 127 128 129 132 134 141 143 144 147 148 149 152 154 156 157 158 160 161 163 ...

output:

808995810

result:

ok single line: '808995810'

Test #8:

score: 10
Accepted
time: 76ms
memory: 4096kb

input:

181069441 4621 2722 2336
2 4 5 6 8 10 11 15 17 18 19 20 22 23 25 26 28 29 30 31 32 33 36 38 41 42 45 47 51 52 53 56 57 58 59 61 63 64 65 66 72 76 78 79 81 83 85 86 87 92 93 95 98 100 102 104 105 106 107 108 109 112 113 115 116 117 118 123 124 125 126 128 129 130 132 133 134 135 137 143 144 149 150 1...

output:

65733152

result:

ok single line: '65733152'

Test #9:

score: 10
Accepted
time: 87ms
memory: 4352kb

input:

296047095 7309 5216 3604
0 7 11 12 13 18 19 21 23 26 28 32 33 36 37 39 41 42 43 46 47 49 50 53 55 57 61 63 64 67 68 70 72 74 75 77 78 79 81 88 89 92 93 94 98 102 106 107 108 109 110 112 113 115 116 117 119 120 121 124 125 127 133 134 136 138 139 141 148 149 150 152 154 155 157 160 162 165 166 172 17...

output:

48228415

result:

ok single line: '48228415'

Test #10:

score: 10
Accepted
time: 78ms
memory: 4216kb

input:

126186662 6673 454 3335
0 3 5 7 8 9 10 11 12 13 14 15 17 19 20 21 22 23 25 27 31 35 36 37 41 42 43 44 45 46 47 49 50 51 52 60 65 67 68 69 71 72 73 74 75 77 79 80 81 82 83 85 87 88 89 90 91 93 94 96 97 101 102 109 110 111 112 114 118 121 122 124 125 127 132 133 135 137 140 143 146 148 149 150 151 152...

output:

377898802

result:

ok single line: '377898802'