QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#336556 | #8285. Shell Sort | ucup-team1198# | WA | 803ms | 85576kb | C++20 | 6.4kb | 2024-02-24 17:46:09 | 2024-02-24 17:46:09 |
Judging History
answer
#pragma GCC target("popcnt")
#include <map>
#include <set>
#include <array>
#include <cmath>
#include <deque>
#include <bitset>
#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
using namespace std;
const int MOD = 1e9 + 7;
int add(int a, int b) {
if (a + b < MOD)
return a + b;
return a + b - MOD;
}
int sub(int a, int b) {
if (a >= b)
return a - b;
return a + MOD - b;
}
int mul(int a, int b) {
return a * 1ll * b % MOD;
}
const int K = 10;
int cnt[K + 1][K + 1];
int subs[K + 1][K + 1];
int highest[K + 1][K + 1][K + 1];
int high_bit[K + 1][K + 1][K + 1];
// (i, mask)
pair<int, int> get_next(pair<int, int> cur, int t, int& cnt) {
int i = cur.first;
int mask = cur.second;
int new_mask = 0;
int new_i = 0;
for (int r = 0; r < t; ++r) {
int cur_mask = mask & subs[t][r];
int kk = __builtin_popcount(cur_mask);
new_mask += highest[t][r][kk];
if (r == i % t) {
cnt += __builtin_popcount(cur_mask & ((1 << i) - 1));
new_i = high_bit[t][r][kk];
}
}
return make_pair(new_i, new_mask);
}
pair<int, int> dp[(1 << 20) + 228][10];
int st;
int n, m;
vector<int> d;
vector<int> block_sz;
vector<int> tmp;
pair<int, int> operator+(const pair<int, int>& a, int x) {
return make_pair(a.first + x, a.second);
}
pair<int, int> combine(const pair<int, int>& a, const pair<int, int>& b) {
if (a.first == b.first)
return make_pair(a.first, add(a.second, b.second));
return max(a, b);
}
int get_tmp_id() {
int ans = 0;
for (int i = 0; i < st; ++i)
ans = ans * (block_sz[i] + 1) + tmp[i];
return ans;
}
int get_tmp_mask() {
int ans = 0;
for (int i = 0; i < st; ++i) {
ans += highest[st][i][tmp[i]];
}
return ans;
}
void go_calc(int i, int total) {
if (i == st) {
if (total <= 1)
return;
int cur_id = get_tmp_id();
int cur_mask = get_tmp_mask();
for (int kek = 0; kek < st; ++kek) {
if (tmp[kek] == 0)
continue;
int i = high_bit[st][kek][tmp[kek]];
--tmp[kek];
int extra = 0;
pair<int, int> have(i, cur_mask);
for (int j = 1; j < m; ++j) {
have = get_next(have, d[j], extra);
}
int prv = get_tmp_id();
for (int j = 0; j < st; ++j)
dp[cur_id][kek] = combine(dp[cur_id][kek], dp[prv][j] + extra);
++tmp[kek];
}
return;
}
for (int j = 0; j <= block_sz[i]; ++j) {
tmp[i] = j;
go_calc(i + 1, total + j);
}
}
void insert_sort(vector<int>& v, int& swap_count) {
int n = v.size();
for (int i = 0; i < n; ++i) {
for (int j = i; j && v[j] < v[j - 1]; --j) {
swap(v[j], v[j - 1]);
++swap_count;
}
}
}
void work(int t, vector<int> &A, int& swap_count) {
for (int i = 0; i < t; ++i) {
vector<int> v;
for (int j = i; j < n; j += t)
v.push_back(A[j]);
insert_sort(v, swap_count);
for (int j = i, k = 0; j < n; j += t, ++k)
A[j] = v[k];
}
}
int shell_sort(vector<int> A) {
int swap_count = 0;
for (int i = 0; i < m; ++i) {
work(d[i], A, swap_count);
}
return swap_count;
}
pair<int, int> solve_dumb() {
vector<int> p(n);
for (int i = 0; i < n; ++i)
p[i] = i;
int bbest = -1e9;
int cnt = 0;
while (true) {
int cur = shell_sort(p);
if (cur > bbest) {
bbest = cur;
cnt = 1;
} else if (cur == bbest) {
++cnt;
}
if (!next_permutation(p.begin(), p.end()))
break;
}
return make_pair(bbest, cnt);
}
//#define STRESS
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef STRESS
for (int kek = 0; ; ++kek) {
if (kek % 100 == 0)
cerr << kek << '\n';
n = rand() % 4 + 1;
int mask = (rand() % (1 << 9)) * 2 + 1;
m = __builtin_popcount(mask);
d.clear();
for (int i = 9; i >= 0; --i) {
if (mask & (1 << i))
d.emplace_back(i + 1);
}
#else
cin >> n >> m;
d.resize(m);
for (int i = 0; i < m; ++i)
cin >> d[i];
#endif
for (int t = 1; t <= K; ++t) {
fill(cnt[t], cnt[t] + t, 0);
fill(subs[t], subs[t] + t, 0);
for (int j = n - 1; j >= 0; --j) {
++cnt[t][j % t];
subs[t][j % t] += 1 << j;
highest[t][j % t][cnt[t][j % t]] = subs[t][j % t];
high_bit[t][j % t][cnt[t][j % t]] = j;
}
}
st = d[0];
int have_already = 0;
block_sz.resize(st);
fill(block_sz.begin(), block_sz.end(), 0);
for (int i = 0; i < n; ++i)
++block_sz[i % st];
for (int i = 0; i < st; ++i)
have_already += block_sz[i] * (block_sz[i] - 1) / 2;
int total_states = 1;
for (int x : block_sz)
total_states *= x + 1;
for (int j = 0; j < total_states; ++j) {
fill(dp[j], dp[j] + st, make_pair(-1e9, 0));
}
tmp.resize(st);
fill(tmp.begin(), tmp.end(), 0);
for (int i = 0; i < st && block_sz[i]; ++i) {
++tmp[i];
dp[get_tmp_id()][i] = make_pair(have_already, 1);
--tmp[i];
}
go_calc(0, 0);
pair<int, int> ans(-1e9, 0);
for (int i = 0; i < st; ++i)
tmp[i] = block_sz[i];
int cur = get_tmp_id();
for (int j = 0; j < st; ++j)
ans = combine(ans, dp[cur][j]);
#ifdef STRESS
auto dumb_ans = solve_dumb();
if (ans != dumb_ans) {
cerr << "BUG!!\n";
cerr << n << ' ' << m << '\n';
for (int x : d)
cerr << x << ' ';
cerr << '\n';
cerr << "wrong: " << ans.first << ',' << ans.second << '\n';
cerr << "right: " << dumb_ans.first << ',' << dumb_ans.second << '\n';
cerr << '\n';
}
assert(ans == dumb_ans);
}
#else
cout << ans.first << ' ' << ans.second << '\n';
#endif
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3644kb
input:
2 2 2 1
output:
1 1
result:
ok 2 number(s): "1 1"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3860kb
input:
5 4 5 4 2 1
output:
6 4
result:
ok 2 number(s): "6 4"
Test #3:
score: 0
Accepted
time: 1ms
memory: 3596kb
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: 3864kb
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: 1ms
memory: 3876kb
input:
8 3 8 7 1
output:
22 7
result:
ok 2 number(s): "22 7"
Test #6:
score: 0
Accepted
time: 0ms
memory: 3568kb
input:
8 1 1
output:
28 1
result:
ok 2 number(s): "28 1"
Test #7:
score: 0
Accepted
time: 1ms
memory: 3816kb
input:
16 2 6 1
output:
77 15
result:
ok 2 number(s): "77 15"
Test #8:
score: 0
Accepted
time: 7ms
memory: 4564kb
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: 4ms
memory: 4488kb
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: 7ms
memory: 4440kb
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: 1ms
memory: 3884kb
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: 3944kb
input:
22 3 5 3 1
output:
100 1
result:
ok 2 number(s): "100 1"
Test #13:
score: 0
Accepted
time: 0ms
memory: 3596kb
input:
22 1 1
output:
231 1
result:
ok 2 number(s): "231 1"
Test #14:
score: 0
Accepted
time: 43ms
memory: 11728kb
input:
22 4 10 8 3 1
output:
97 4
result:
ok 2 number(s): "97 4"
Test #15:
score: 0
Accepted
time: 50ms
memory: 11732kb
input:
22 5 10 7 6 3 1
output:
92 70
result:
ok 2 number(s): "92 70"
Test #16:
score: 0
Accepted
time: 52ms
memory: 11732kb
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: 75ms
memory: 11804kb
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: 1ms
memory: 4008kb
input:
14 2 10 1
output:
61 210
result:
ok 2 number(s): "61 210"
Test #19:
score: 0
Accepted
time: 0ms
memory: 3664kb
input:
18 2 2 1
output:
117 1
result:
ok 2 number(s): "117 1"
Test #20:
score: 0
Accepted
time: 105ms
memory: 43596kb
input:
30 2 9 1
output:
264 84
result:
ok 2 number(s): "264 84"
Test #21:
score: 0
Accepted
time: 81ms
memory: 35808kb
input:
29 2 9 1
output:
253 36
result:
ok 2 number(s): "253 36"
Test #22:
score: 0
Accepted
time: 16ms
memory: 9976kb
input:
25 2 8 1
output:
195 8
result:
ok 2 number(s): "195 8"
Test #23:
score: 0
Accepted
time: 453ms
memory: 85500kb
input:
30 4 10 9 5 1
output:
188 40
result:
ok 2 number(s): "188 40"
Test #24:
score: 0
Accepted
time: 803ms
memory: 85560kb
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: -100
Wrong Answer
time: 743ms
memory: 85576kb
input:
30 8 10 9 8 7 4 3 2 1
output:
202 6
result:
wrong answer 1st numbers differ - expected: '154', found: '202'