QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#336556#8285. Shell Sortucup-team1198#WA 803ms85576kbC++206.4kb2024-02-24 17:46:092024-02-24 17:46:09

Judging History

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

  • [2024-02-24 17:46:09]
  • 评测
  • 测评结果:WA
  • 用时:803ms
  • 内存:85576kb
  • [2024-02-24 17:46:09]
  • 提交

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'