QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#336318 | #8285. Shell Sort | ucup-team087# | WA | 0ms | 3864kb | C++14 | 6.1kb | 2024-02-24 14:59:03 | 2024-02-24 14:59:03 |
Judging History
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;
}
詳細信息
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'