QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#336318#8285. Shell Sortucup-team087#WA 0ms3864kbC++146.1kb2024-02-24 14:59:032024-02-24 14:59:03

Judging History

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

  • [2024-02-24 14:59:03]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3864kb
  • [2024-02-24 14:59:03]
  • 提交

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) {
      ret += __builtin_popcount((q & mask[m][i % D[m]][N]) >> i);
      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: 0ms
memory: 3864kb

input:

2 2
2 1

output:

1 1

result:

ok 2 number(s): "1 1"

Test #2:

score: -100
Wrong Answer
time: 0ms
memory: 3832kb

input:

5 4
5 4 2 1

output:

10 26

result:

wrong answer 1st numbers differ - expected: '6', found: '10'