QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#337660#8285. Shell Sorthos_lyricAC ✓1450ms11516kbC++146.2kb2024-02-25 12:56:152024-02-25 12:56:15

Judging History

你现在查看的是最新测评结果

  • [2024-02-25 12:56:15]
  • 评测
  • 测评结果:AC
  • 用时:1450ms
  • 内存:11516kb
  • [2024-02-25 12:56:15]
  • 提交

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>;


using Pair = pair<int, Mint>;
constexpr int INF = 1001001001;


constexpr int MAX_N = 30;
constexpr int MAX_M = 10;
constexpr int MAX_D = 10;

Pair solve(int N, int M, const vector<int> &D) {
  const int E = D[0];
  int base = 0;
  int ls[MAX_D] = {}, ms[MAX_D + 1] = {1};
  for (int r = 0; r < E; ++r) {
    for (int i = r; i < N; i += E) ++ls[r];
    base += ls[r] * (ls[r] - 1) / 2;
    ms[r + 1] = ms[r] * (ls[r] + 1);
  }
// cerr<<"base = "<<base<<endl;cerr<<"ls = ";pv(ls,ls+E);cerr<<"ms = ";pv(ms,ms+(E+1));
  
  // 1: small
  int mask[MAX_M][MAX_D][MAX_N + 1] = {};
  for (int m = 0; m < M; ++m) {
    for (int r = 0; r < D[m]; ++r) {
      int pop = 0;
      mask[m][r][0] = 0;
      for (int i = r; i < N; i += D[m]) {
        mask[m][r][pop + 1] = mask[m][r][pop] | 1 << i;
        ++pop;
      }
      for (; pop < N; ) {
        mask[m][r][pop + 1] = mask[m][r][pop];
        ++pop;
      }
    }
  }
  
  auto simulate = [&](int q0, int i0) -> int {
    int ret = 0;
    int q = q0;
    int i = i0;
    for (int m = 1; m < M; ++m) {
      {
        const int r = i % D[m];
        const int o = q & mask[m][r][N];
        ret += __builtin_popcount(o >> i);
        i = r + D[m] * __builtin_popcount(o);
      }
      int qq = 0;
      for (int r = 0; r < D[m]; ++r) {
        qq |= mask[m][r][__builtin_popcount(q & mask[m][r][N])];
      }
      q = qq;
    }
// cerr<<"[simulate] q0 = "<<q0<<", i0 = "<<i0<<": ret = "<<ret<<endl;
    return ret;
  };
  
  vector<Pair> dp(ms[E], Pair(-INF, 0));
  dp[0] = Pair(0, 1);
  for (int p = 0; p < ms[E]; ++p) {
    int xs[MAX_D];
    for (int r = 0; r < E; ++r) xs[r] = p / ms[r] % (ls[r] + 1);
    int q = 0;
    for (int r = 0; r < E; ++r) q |= mask[0][r][xs[r]];
    for (int r = 0; r < E; ++r) if (xs[r] < ls[r]) {
      const int pp = p + ms[r];
      const int cost = dp[p].first + simulate(q, r + D[0] * xs[r]);
      const Mint way = dp[p].second;
      if (dp[pp].first < cost) dp[pp] = make_pair(cost, 0);
      if (dp[pp].first == cost) dp[pp].second += way;
    }
  }
// cerr<<"dp = "<<dp<<endl;
  Pair ans = dp.back();
  ans.first += base;
  return ans;
}

int main() {
  int N, M;
  for (; ~scanf("%d%d", &N, &M); ) {
    vector<int> D(M);
    for (int m = 0; m < M; ++m) {
      scanf("%d", &D[m]);
    }
    
    const auto ans = solve(N, M, D);
    printf("%d %u\n", ans.first, ans.second.x);
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

2 2
2 1

output:

1 1

result:

ok 2 number(s): "1 1"

Test #2:

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

input:

5 4
5 4 2 1

output:

6 4

result:

ok 2 number(s): "6 4"

Test #3:

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

input:

8 4
6 3 2 1

output:

15 4

result:

ok 2 number(s): "15 4"

Test #4:

score: 0
Accepted
time: 1ms
memory: 4080kb

input:

8 6
8 7 5 4 2 1

output:

14 2

result:

ok 2 number(s): "14 2"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3836kb

input:

8 3
8 7 1

output:

22 7

result:

ok 2 number(s): "22 7"

Test #6:

score: 0
Accepted
time: 1ms
memory: 3836kb

input:

8 1
1

output:

28 1

result:

ok 2 number(s): "28 1"

Test #7:

score: 0
Accepted
time: 1ms
memory: 3796kb

input:

16 2
6 1

output:

77 15

result:

ok 2 number(s): "77 15"

Test #8:

score: 0
Accepted
time: 11ms
memory: 3856kb

input:

16 8
10 9 8 7 6 5 4 1

output:

57 5

result:

ok 2 number(s): "57 5"

Test #9:

score: 0
Accepted
time: 14ms
memory: 4144kb

input:

16 10
10 9 8 7 6 5 4 3 2 1

output:

57 3

result:

ok 2 number(s): "57 3"

Test #10:

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

input:

16 7
10 9 8 6 5 4 1

output:

49 1

result:

ok 2 number(s): "49 1"

Test #11:

score: 0
Accepted
time: 2ms
memory: 3836kb

input:

16 4
7 6 2 1

output:

52 9

result:

ok 2 number(s): "52 9"

Test #12:

score: 0
Accepted
time: 1ms
memory: 4100kb

input:

22 3
5 3 1

output:

100 1

result:

ok 2 number(s): "100 1"

Test #13:

score: 0
Accepted
time: 1ms
memory: 4072kb

input:

22 1
1

output:

231 1

result:

ok 2 number(s): "231 1"

Test #14:

score: 0
Accepted
time: 47ms
memory: 4064kb

input:

22 4
10 8 3 1

output:

97 4

result:

ok 2 number(s): "97 4"

Test #15:

score: 0
Accepted
time: 61ms
memory: 3872kb

input:

22 5
10 7 6 3 1

output:

92 70

result:

ok 2 number(s): "92 70"

Test #16:

score: 0
Accepted
time: 80ms
memory: 4152kb

input:

22 6
10 9 8 7 3 1

output:

97 1

result:

ok 2 number(s): "97 1"

Test #17:

score: 0
Accepted
time: 133ms
memory: 4028kb

input:

22 10
10 9 8 7 6 5 4 3 2 1

output:

109 1

result:

ok 2 number(s): "109 1"

Test #18:

score: 0
Accepted
time: 0ms
memory: 3804kb

input:

14 2
10 1

output:

61 210

result:

ok 2 number(s): "61 210"

Test #19:

score: 0
Accepted
time: 1ms
memory: 3836kb

input:

18 2
2 1

output:

117 1

result:

ok 2 number(s): "117 1"

Test #20:

score: 0
Accepted
time: 71ms
memory: 7332kb

input:

30 2
9 1

output:

264 84

result:

ok 2 number(s): "264 84"

Test #21:

score: 0
Accepted
time: 58ms
memory: 6524kb

input:

29 2
9 1

output:

253 36

result:

ok 2 number(s): "253 36"

Test #22:

score: 0
Accepted
time: 12ms
memory: 3960kb

input:

25 2
8 1

output:

195 8

result:

ok 2 number(s): "195 8"

Test #23:

score: 0
Accepted
time: 527ms
memory: 11364kb

input:

30 4
10 9 5 1

output:

188 40

result:

ok 2 number(s): "188 40"

Test #24:

score: 0
Accepted
time: 1326ms
memory: 11328kb

input:

30 9
10 9 8 7 6 5 4 3 1

output:

184 6

result:

ok 2 number(s): "184 6"

Test #25:

score: 0
Accepted
time: 1116ms
memory: 11360kb

input:

30 8
10 9 8 7 4 3 2 1

output:

154 1

result:

ok 2 number(s): "154 1"

Test #26:

score: 0
Accepted
time: 1127ms
memory: 11416kb

input:

30 8
10 8 7 6 5 4 3 1

output:

155 1

result:

ok 2 number(s): "155 1"

Test #27:

score: 0
Accepted
time: 824ms
memory: 11516kb

input:

30 6
10 8 6 4 3 1

output:

150 4

result:

ok 2 number(s): "150 4"

Test #28:

score: 0
Accepted
time: 1450ms
memory: 11412kb

input:

30 10
10 9 8 7 6 5 4 3 2 1

output:

184 6

result:

ok 2 number(s): "184 6"

Test #29:

score: 0
Accepted
time: 627ms
memory: 9368kb

input:

29 6
10 9 7 5 3 1

output:

129 200

result:

ok 2 number(s): "129 200"

Extra Test:

score: 0
Extra Test Passed