QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#463871#7308. Permutation and noitatumrePhos_lyricAC ✓75ms3800kbC++147.5kb2024-07-05 15:23:482024-07-05 15:23:48

Judging History

This is the latest submission verdict.

  • [2024-07-05 15:23:48]
  • Judged
  • Verdict: AC
  • Time: 75ms
  • Memory: 3800kb
  • [2024-07-05 15:23:48]
  • 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 = 1000000007;
using Mint = ModInt<MO>;


vector<Mint> findLinearRecurrence(const vector<Mint> &as) {
  const int n = as.size();
  int d = 0, m = 0;
  vector<Mint> cs(n + 1, 0), bs(n + 1, 0);
  cs[0] = bs[0] = 1;
  Mint invBef = 1;
  for (int i = 0; i < n; ++i) {
    ++m;
    Mint dif = as[i];
    for (int j = 1; j < d + 1; ++j) dif += cs[j] * as[i - j];
    if (dif.x != 0) {
      auto csDup = cs;
      const Mint r = dif * invBef;
      for (int j = m; j < n; ++j) cs[j] -= r * bs[j - m];
      if (2 * d <= i) {
        d = i + 1 - d;
        m = 0;
        bs = csDup;
        invBef = dif.inv();
      }
    }
  }
  cs.resize(d + 1);
  return cs;
}

// x^e mod rev(cs)
vector<Mint> powerRev(const vector<Mint> &cs, Int e) {
  assert(!cs.empty());
  assert(cs[0] == 1);
  const int d = (int)cs.size() - 1;
  if (d == 0) {
    return {};
  } else if (d == 1) {
    return {(-cs[1]).pow(e)};
  }
  auto mul = [&](const vector<Mint> &fs, const vector<Mint> &gs) {
    vector<Mint> hs(d + d - 1, 0);
    for (int i = 0; i < d; ++i) for (int j = 0; j < d; ++j) {
      hs[i + j] += fs[i] * gs[j];
    }
    for (int i = d + d - 1; --i >= d; ) {
      for (int j = 1; j <= d; ++j) {
        hs[i - j] -= cs[j] * hs[i];
      }
    }
    hs.resize(d);
    return hs;
  };
  vector<Mint> xs(d, 0), ys(d, 0);
  xs[1] = 1;
  ys[0] = 1;
  for (; ; xs = mul(xs, xs)) {
    if (e & 1) ys = mul(ys, xs);
    if (!(e >>= 1)) break;
  }
  return ys;
}

Mint linearRecurrenceAt(const vector<Mint> &as, const vector<Mint> &cs, Int e) {
  assert(!cs.empty());
  assert(cs[0] == 1);
  const int d = (int)cs.size() - 1;
  assert((int)as.size() >= d);
  const auto fs = powerRev(cs, e);
  Mint ans = 0;
  for (int i = 0; i < d; ++i) {
    ans += fs[i] * as[i];
  }
  return ans;
}


void exper() {
  for (int N = 1; N <= 8; ++N) {
    int all = 0;
    vector<int> ps(N);
    for (int i = 0; i < N; ++i) ps[i] = i + 1;
    do {
      vector<int> qs(N+N);
      for (int i = 0; i < N; ++i) qs[i] = qs[N+N - 1 - i] = ps[i];
      bool ok = true;
      for (int a = 0; a < N+N; ++a) for (int b = a + 1; b < N+N; ++b) for (int c = b + 1; c < N+N; ++c) for (int d = c + 1; d < N+N; ++d) {
        ok = ok && !(qs[a] < qs[c] && qs[c] < qs[d] && qs[d] < qs[b]);
      }
      if (ok) {
        ++all;
        cout << ps << endl;
      }
    } while (next_permutation(ps.begin(), ps.end()));
    cerr << "N = " << N << ": " << all << endl;
  }
}
/*
N = 1: 1
N = 2: 2
N = 3: 6
N = 4: 16
N = 5: 36
N = 6: 80
N = 7: 178
N = 8: 394
*/

int main() {
  // exper();
  
  constexpr int M = 100;
  vector<Mint> dp(M);
  dp[0] = 1;
  dp[1] = 1;
  dp[2] = 2;
  dp[3] = 6;
  for (int n = 4; n < M; ++n) {
    /*
      insert n
      - left side: empty
          n, [1, n-1]
      - left side: min = x, max = y
          conditions about n
            x, n, ?, ?': right side has (<= 1) value in [x+1, n-1]
            x, n, ?', ?': right side has no value in [x+1, y-1]
            1, n', ?, ?: left side is incr. in [2, n-1]
          - y = n-2
              2,...,n-2, n, n-1;  insert 1 into left side
              2,...,n-2, n, 1, n-1
              x,...,n-2, n, n-1, [1, x-1]  (2 <= x <= n-2)
          - y = n-1
              2,...,n-1, n;  insert 1 into left side
              x,...,n-1, n, [1, x-1]  (2 <= x <= n-1)
    */
    dp[n] += dp[n-1];
    dp[n] += (n-2);
    dp[n] += 1;
    for (int x = 2; x <= n-2; ++x) dp[n] += dp[x-1];
    dp[n] += (n-1);
    for (int x = 2; x <= n-1; ++x) dp[n] += dp[x-1];
  }
cerr<<"dp = "<<dp<<endl;
  const auto cs = findLinearRecurrence(dp);
cerr<<"cs = "<<cs<<endl;
  
  Int N;
  for (; ~scanf("%lld", &N); ) {
    const Mint ans = linearRecurrenceAt(dp, cs, N);
    printf("%u\n", ans.x);
  }
  return 0;
}

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3776kb

input:

4
1000000000

output:

16
861159011

result:

ok 2 number(s): "16 861159011"

Test #2:

score: 0
Accepted
time: 75ms
memory: 3800kb

input:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...

output:

1
2
6
16
36
80
178
394
870
1920
4236
9344
20610
45458
100262
221136
487732
1075728
2372594
5232922
11541574
25455744
56144412
123830400
273116546
602377506
328585407
930287362
462952218
254489838
439267033
341486279
937462398
314191817
969869915
877202216
68596237
107062384
91326979
251250197
609562...

result:

ok 20000 numbers

Extra Test:

score: 0
Extra Test Passed