QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#723981#4264. 普罗达科特hos_lyric100 ✓2258ms7256kbC++148.8kb2024-11-08 06:26:172024-11-08 06:26:17

Judging History

This is the latest submission verdict.

  • [2024-11-08 06:26:17]
  • Judged
  • Verdict: 100
  • Time: 2258ms
  • Memory: 7256kb
  • [2024-11-08 06:26:17]
  • Submitted

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")

////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
  static constexpr unsigned M = M_;
  unsigned x;
  constexpr ModInt() : x(0U) {}
  constexpr ModInt(unsigned x_) : x(x_ % M) {}
  constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
  constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
  constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
  ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
  ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
  ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
  ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
  ModInt pow(long long e) const {
    if (e < 0) return inv().pow(-e);
    ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
  }
  ModInt inv() const {
    unsigned a = M, b = x; int y = 0, z = 1;
    for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
    assert(a == 1U); return ModInt(y);
  }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
  ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
  ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
  ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
  ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
  template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
  template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
  template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
  template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
  explicit operator bool() const { return x; }
  bool operator==(const ModInt &a) const { return (x == a.x); }
  bool operator!=(const ModInt &a) const { return (x != a.x); }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////

constexpr unsigned MO = 1'000'000'021;
using Mint = ModInt<MO>;

constexpr int LIM_INV = 1010;
Mint inv[LIM_INV], fac[LIM_INV], invFac[LIM_INV];

void prepare() {
  inv[1] = 1;
  for (int i = 2; i < LIM_INV; ++i) {
    inv[i] = -((Mint::M / i) * inv[Mint::M % i]);
  }
  fac[0] = invFac[0] = 1;
  for (int i = 1; i < LIM_INV; ++i) {
    fac[i] = fac[i - 1] * i;
    invFac[i] = invFac[i - 1] * inv[i];
  }
}
Mint binom(Int n, Int k) {
  if (n < 0) {
    if (k >= 0) {
      return ((k & 1) ? -1 : +1) * binom(-n + k - 1, k);
    } else if (n - k >= 0) {
      return (((n - k) & 1) ? -1 : +1) * binom(-k - 1, n - k);
    } else {
      return 0;
    }
  } else {
    if (0 <= k && k <= n) {
      assert(n < LIM_INV);
      return fac[n] * invFac[k] * invFac[n - k];
    } else {
      return 0;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

// mod rev(qs)  (deg(rev(qs)) = K)
vector<Mint> mod(vector<Mint> as, const vector<Mint> &qs) {
  const int deg = (int)qs.size() - 1;
  for (int i = (int)as.size(); --i >= deg; ) for (int j = 1; j <= deg; ++j) as[i - j] -= qs[j] * as[i];
  as.resize(deg, 0);
  return as;
}
vector<Mint> mul(const vector<Mint> &as, const vector<Mint> &bs, const vector<Mint> &qs) {
  const int deg = (int)qs.size() - 1;
  vector<Mint> cs(deg + deg - 1, 0);
  for (int i = 0; i < deg; ++i) for (int j = 0; j < deg; ++j) cs[i + j] += as[i] * bs[j];
  return mod(cs, qs);
}
vector<Mint> power(Int e, const vector<Mint> &qs) {
  const int deg = (int)qs.size() - 1;
  if (deg == 0) return {};
  if (deg == 1) return {(-qs[1]).pow(e)};
  vector<Mint> as(deg, 0), bs(deg, 0);
  as[1] = 1;
  bs[0] = 1;
  for (; ; as = mul(as, as, qs)) {
    if (e & 1) bs = mul(bs, as, qs);
    if (!(e >>= 1)) return bs;
  }
}


/*
  c: part of partition of K
    1 / (1 - x^c)
    PIE: (1 - x^((b+1)c)) / (1 - x^c)
*/

int N, K;
vector<Int> A, B;

// x^* mod rev(LCM of all possble Q(x))
int DEG;
vector<Mint> LCM;
vector<int> limIs;
vector<vector<vector<Mint>>> rss;

// [x^a] x^((b+1)i) / Q(x)
vector<vector<Mint>> at;

Mint sub(int c, const vector<int> &fs, Mint w, const vector<Mint> &ps) {
  Mint ret = 0;
  if (!c) {
    ret = w;
    for (int n = 0; n < N; ++n) {
      Mint sum = 0;
      for (int i = 0; i < (int)ps.size(); ++i) {
        sum += ps[i] * at[n][i];
      }
      ret *= sum;
    }
  } else {
    auto pps = ps;
    for (int g = 0; ; ++g) {
      ret += sub(c - 1, fs, w * binom(fs[c], g) * (g&1?-1:+1), pps);
      if (g == fs[c]) break;
      pps.resize((int)pps.size() + c, 0);
      for (int i = (int)pps.size(); --i >= c; ) pps[i] -= pps[i - c];
    }
  }
  return ret;
}

Mint ans0, ans1;

void dfs(int k, int c, vector<int> &fs, int s, Mint w) {
  if (!k) {
    // 1 / \prod[c] (1 - x^c)
    vector<Mint> seq(DEG, 0);
    seq[0] = 1;
    for (c = 1; c <= K; ++c) for (int f = 0; f < fs[c]; ++f) {
      for (int i = c; i < DEG; ++i) seq[i] += seq[i - c];
    }
    at.assign(N, vector<Mint>(K + 1, 0));
    for (int n = 0; n < N; ++n) {
      for (int i = limIs[n]; i >= 0; --i) {
        for (int j = 0; j < DEG; ++j) {
          at[n][i] += rss[n][i][j] * seq[j];
        }
      }
    }
    const Mint res = sub(K, fs, 1, {1});
    ans0 += s * w * res;
    ans1 += w * res;
  } else {
    for (chmin(c, k); c; --c) {
      int ss = s;
      Mint ww = w;
      for (int f = 1; f * c <= k; ++f) {
        fs[c] = f;
        if ((c-1)&1) ss = -ss;
        ww *= inv[c];
        ww *= inv[f];
        dfs(k - f * c, c - 1, fs, ss, ww);
      }
      fs[c] = 0;
    }
  }
}

int main() {
  prepare();
  
  for (; ~scanf("%d%d", &N, &K); ) {
    A.resize(N); for (int n = 0; n < N; ++n) scanf("%lld", &A[n]);
    B.resize(N); for (int n = 0; n < N; ++n) scanf("%lld", &B[n]);
    
    // \prod[1<=c<=K] \Phi[c](x)^floor(K/c) = \prod[1<=c<=K] (1 - x^c)
    LCM = {1};
    for (int c = 1; c <= K; ++c) {
      LCM.resize((int)LCM.size() + c, 0);
      for (int i = (int)LCM.size(); --i >= c; ) LCM[i] -= LCM[i - c];
    }
    DEG = (int)LCM.size() - 1;
    
    // x^(2^e) mod rev(LCM)
    constexpr int E = 60;
    vector<Mint> two[E];
    two[0].assign(DEG, 0);
    if (DEG == 1) {
      two[0][0] = -LCM[1];
    } else {
      two[0][1] = 1;
    }
    for (int e = 1; e < E; ++e) two[e] = mul(two[e - 1], two[e - 1], LCM);
    auto power = [&](Int a) -> vector<Mint> {
      vector<Mint> as(DEG, 0);
      as[0] = 1;
      for (int e = E; --e >= 0; ) if (a >> e & 1) as = mul(as, two[e], LCM);
      return as;
    };
    
    limIs.resize(N);
    rss.resize(N);
    for (int n = 0; n < N; ++n) {
      const auto bs = power(B[n] + 1);
      limIs[n] = min<Int>(A[n] / (B[n] + 1), K);
      rss[n].resize(limIs[n] + 1);
      rss[n][limIs[n]] = power(A[n] - (B[n] + 1) * limIs[n]);
      for (int i = limIs[n]; --i >= 0; ) {
        rss[n][i] = mul(rss[n][i + 1], bs, LCM);
      }
    }
    
    ans0 = ans1 = 0;
    vector<int> fs(K + 1, 0);
    dfs(K, K, fs, 1, 1);
    
    printf("%u %u\n", ans0.x, ans1.x);
  }
  return 0;
}

详细


Pretests


Final Tests

Test #1:

score: 10
Accepted
time: 0ms
memory: 3792kb

input:

5 3
5 4 4 5 5
1 2 0 3 3

output:

244327 244508

result:

ok your answer is completely correct

Test #2:

score: 10
Accepted
time: 0ms
memory: 3892kb

input:

10 5
2 13 10 5 19 1 1 13 0 10
9 9 4 4 2 4 11 7 8 0

output:

195072166 491216037

result:

ok your answer is completely correct

Test #3:

score: 10
Accepted
time: 85ms
memory: 4116kb

input:

1 25
859237255572571385
383756148

output:

76148239 57278645

result:

ok your answer is completely correct

Test #4:

score: 10
Accepted
time: 393ms
memory: 5636kb

input:

50 20
426 296 500 770 196 205 8 3 553 715 326 774 308 771 692 321 266 875 695 808 480 663 875 29 211 934 41 870 108 684 718 93 469 795 715 179 875 643 612 16 869 671 70 747 183 262 970 758 461 943
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

output:

713551357 827257512

result:

ok your answer is completely correct

Test #5:

score: 10
Accepted
time: 2258ms
memory: 7256kb

input:

50 25
659963088403836261 276297116698148579 977561384919365549 755976933383675623 83755198145180443 57994910200007461 31981730757608017 962107427409896439 936699403403032539 781021169701247249 889868607589650686 475849021824792967 227991564557474573 460135246078872781 327156553850723939 339557274953...

output:

42201610 954163630

result:

ok your answer is completely correct

Test #6:

score: 10
Accepted
time: 6ms
memory: 3984kb

input:

50 10
6896 33 3927 3822 521 1336 8895 7170 7131 8459 9452 8869 4048 8208 8553 6557 6325 2925 3963 6693 9845 4718 6288 1077 192 6715 9409 9570 1035 6698 7678 5217 5259 4783 7590 9844 2010 6166 2660 4001 633 3622 1761 2165 880 2163 5694 3074 2721 909
9931 1158 126 565 5487 3252 164 6174 701 162 483 81...

output:

909814761 984530806

result:

ok your answer is completely correct

Test #7:

score: 10
Accepted
time: 28ms
memory: 4040kb

input:

50 10
629848219585363864 102965794934301173 228515996227729879 923083234501447752 784422529458169066 656094245184762446 709006128455493371 378519810944419730 119114275566221576 325774773382278466 794833088219072631 804254141902904173 149664468627269733 462155266609850330 300848226478386216 720861337...

output:

92785316 131906283

result:

ok your answer is completely correct

Test #8:

score: 10
Accepted
time: 153ms
memory: 4472kb

input:

50 15
931950683432368905 252272584206164264 301632752330220137 53619976112576416 76333681916389374 932355337095363698 369613714585329489 934856938106685055 439984364351610204 415797106884413432 486323835735654853 438065880727548931 996451182235044934 219767189395692389 584720282009659139 91247361420...

output:

71932603 160290152

result:

ok your answer is completely correct

Test #9:

score: 10
Accepted
time: 623ms
memory: 5692kb

input:

50 20
340058827925871359 746616902820113138 712089122944977597 278285732844380429 67976124155010217 407533896664832973 643696626322695029 98673866701392503 179305405085618398 406341742157090568 685138979411565654 658110337606804515 26201171084935567 496518709102052471 823268827959648339 813529869260...

output:

638470704 525470110

result:

ok your answer is completely correct

Test #10:

score: 10
Accepted
time: 2115ms
memory: 6432kb

input:

50 25
70550195088392938 462173953698106930 736748745821570895 118753550383340689 364892649137871522 15311256274115095 39936508357206247 642638638386907547 411533590762510563 470356915279154303 192964900448962613 985859081860794747 60285035155481992 834889097497214844 2550873406735039 465323891343642...

output:

743167681 122857881

result:

ok your answer is completely correct

Extra Test:

score: 0
Extra Test Passed